You are on page 1of 276

Architecture and Design Guide

Sun Java Wireless Client Software 2.2 Java Platform, Micro Edition

Sun Microsystems, Inc. www.sun.com

December 2008

Copyright 2008 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. All rights reserved. Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product that is described in this document. In particular, and without limitation, these intellectual property rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or more additional patents or pending patent applications in the U.S. and in other countries. THIS PRODUCT CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS OF SUN MICROSYSTEMS, INC. USE, DISCLOSURE OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SUN MICROSYSTEMS, INC. U.S. Government Rights - Commercial software. Government users are subject to the Sun Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its supplements. This distribution may include materials developed by third parties. Sun, Sun Microsystems, the Sun logo, Java, Solaris, HotSpot, J2ME, J2SE, J2EE, Java Developer Connection, Java Community Process, JCP, Javadoc, JDK, JavaCall, Java Card, phoneME and the Java Coffee Cup logo are trademarks or registered trademarks of Sun Microsystems, Inc. or its subsidiaries in the U.S. and other countries. UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open Company, Ltd. Intel is a trademark or registered trademark of Intel Corporation or its subsidiaries in the United States and other countries. OpenGL is a registered trademark of Silicon Graphics, Inc. The PostScript logo is a trademark or registered trademark of Adobe Systems, Incorporated, which may be registered in certain jurisdictions. Products covered by and information contained in this service manual are controlled by U.S. Export Control laws and may be subject to the export or import laws in other countries. Nuclear, missile, chemical biological weapons or nuclear maritime end uses or end users, whether direct or indirect, are strictly prohibited. Export or reexport to countries subject to U.S. embargo or to entities identied on U.S. export exclusion lists, including, but not limited to, the denied persons and specially designated nationals lists is strictly prohibited. DOCUMENTATION IS PROVIDED "AS IS" AND ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD TO BE LEGALLY INVALID. Copyright 2008 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, tats-Unis. Tous droits rservs. Sun Microsystems, Inc. dtient les droits de proprit intellectuelle relatifs la technologie incorpore dans le produit qui est dcrit dans ce document. En particulier, et ce sans limitation, ces droits de proprit intellectuelle peuvent inclure un ou plusieurs des brevets amricains lists ladresse http://www.sun.com/patents et un ou plusieurs brevets supplmentaires ou les applications de brevet en attente aux tats Unis et dans dautres pays. CE PRODUIT CONTIENT DES INFORMATIONS CONFIDENTIELLES ET DES SECRETS COMMERCIAUX DE SUN MICROSYSTEMS, INC. SON UTILISATION, SA DIVULGATION ET SA REPRODUCTION SONT INTERDITES SANS L AUTORISATION EXPRESSE, ECRITE ET PREALABLE DE SUN MICROSYSTEMS, INC. Droits du gouvernement des tats-Unis - logiciel commercial. Les droits des utilisateur du gouvernement des tats-Unis sont soumis aux termes de la licence standard Sun Microsystems et aux conditions appliques de la FAR et de ces complments. Cette distribution peut inclure des elements dvelopps par des tiers. Sun, Sun Microsystems, le logo Sun, Java, Solaris, HotSpot, J2ME, J2SE, J2EE, Java Developer Connection, Java Community Process, JCP, Javadoc, JDK, JavaCall, Java Card, phoneME et le logo Java Coffee Cup sont des marques de fabrique ou des marques dposes de Sun Microsystems, Inc., ou ses liales, aux tats-Unis et dans dautres pays. UNIX est une marque dpose aux tats-Unis et dans dautres pays et sous licence exclusive de X/Open Company, Ltd. Intel est une marque dpose de Intel Corporation ou de sa liale aux tats-Unis et dans dautres pays. OpenGL est une marque dpose de Silicon Graphics, Inc. Le logo PostScript est une marque de fabrique ou une marque dpose de Adobe Systems, Incorporated, laquelle pourrait dpose dans certaines juridictions. Les produits qui font lobjet de ce manuel dentretien et les informations quil contient sont rgis par la lgislation amricaine en matire de contrl des exportations et peuvent tre soumis au droit dautres pays dans le domaine des exportations et importations. Les utilisations nales, ou utilisateurs naux, pour des armes nuclaires, des missiles, des armes biologiques et chimiques ou du nuclaire maritime, directement ou indirectement, sont strictement interdites. Les exportations ou rexportations vers des pays sous embargo des tats-Unis, ou vers des entits gurant sur les listes dexclusion dexportation amricaines, y compris, mais de manir non exclusive, la liste de personnes qui font objet dun ordre de ne pas participer, dune faon directe ou indirecte, aux exportations des produits ou des services qui sont rgi par la lgislation amricaine en matire de contrl des exportations et la liste de ressortissants spciquement dsignes, sont rigoureusement interdites. LA DOCUMENTATION EST FOURNIE "EN LTAT" ET TOUTES AUTRES CONDITIONS, DCLARATIONS ET GARANTIES EXPRESSES OU TACITES SONT FORMELLEMENT EXCLUES, DANS LA MESURE AUTORISE PAR LA LOI APPLICABLE, Y COMPRIS NOTAMMENT TOUTE GARANTIE IMPLICITE RELATIVE A LA QUALIT MARCHANDE, A LAPTITUDE A UNE UTILISATION PARTICULIRE OU A LABSENCE DE CONTREFAON.

Contents

Preface 1.

xxi 1 1

Software Overview

Specifications and APIs Architecture 2

MIDP Services and Subsystems Components Control Flow 5 6 7 9

Device Interactions 2. Porting Overview

Build the Software on the Reference Platform Run TCKs on the Reference Port 10

10

Set Up and Configure Your Device Development Environment Port the JavaCall API 12 12

11

Functions and Naming Directory Structure 13

Understanding the Event Module The JavaCall Porting Process 3. 14

13

Hardware and Software Requirements and Constraints

17

iii

Data-Type Assumptions Resource Limitations Native Stack Size 18 18

18

AMS Resource Limitations RMS Resource Limitations

19 19 20 20 20

The system.jam_space Property

The DEFAULT_TOTAL_SPACE Property The STORAGE_SUITE_LIMIT Property Networking Resource Limitations Graphics Resource Limitations Other Resources 4. 21 23 21 21

Managing Properties and Constants Introduction Design 24 25 23

Input Files Properties 28

Modifying Properties

28 28

Adding Properties 29

Constants

Modifying Constants

29 29 31 33 34

Adding Constants

Changing the Output Format of Constants 5.

Using the Logging, Tracing, and Assertion Services

Building to Enable the Logging, Tracing, and Assertion Services Dynamic Logging and a MIDlets JAD File Using the Logging, Tracing, and Assertion APIs Logging 36 35 36

iv

Architecture and Design Guide December 2008

Adding Logging Channels Tracing 38 38

37

Assertions 6.

Porting the Record Management System Design 42 42 43

41

Design Overview

External API and the Sandbox Detailed Design 43

Design Rationale, Notes, and Considerations Database Implementation Detailed Design 44 43

43

Design Rationale, Notes, and Considerations File System Access Porting 7. 45 47 45

44

File Organization and Naming Source Code Organization 47

Naming Convention for Native Files 8. PCSL 57 58 59

54

PCSL Print Library

PCSL Memory Allocation Library

Porting malloc-Based Implementations Porting the Heap-Based Implementation PCSL File System Interface PCSL Networking Library Handles and Contexts 62 64 65

60 61

Alternative Networking Implementations BSD Implementations 68

66

Contents

Socket-over-Serial Implementation Notification 69 70 72

69

PCSL String Library

Porting Unicode Resource Names About Radix 41 Encoding 73

Encoding for Non-English Resource Names 9. PutPixel Technology Porting Building Testing Tuning 10. 75 76 76 76 79 75

74

Low-Level Graphics and Images Services Description 79 80

External Interactions Design 80

Graphics Rendering Component

81 81 82

Primitive Graphics Routines and Porting

Design Rationale, Notes, and Considerations Graphics Context Component Detailed Design Image Component 83 84 85 83

Preprocessor Component Decoder Component Accessor Component 87 89

Image Storage Component Renderer Component Porting 90 90

89

vi

Architecture and Design Guide December 2008

Porting the Primitive Graphics Group

91 92

Porting Checklist for Primitive Graphics Drawing Graphics Primitives 93 101 101

Porting Image Manipulation Group Mutable and Immutable Images

Porting Checklist for the Image Manipulation Group Functions to Port

105

105 105

Facilitating Porting of the Image Manipulation Group 107

String and Font Drawing and Accessing Group Alert Sound Group 108 108 108 109 109

Vibrate and Backlight Group

Backlight Control Methods

Backlighting Porting Interface

Strategies for Porting Backlighting Backlighting Duration 110 110 110

Vibration Control Methods Vibration Porting Interface Vibration Support Network Indicator Porting Strategies Porting Issues 113 113 112 112 111

Porting Verification Error Checking Boundary Cases 113 113

Performance Tuning 11.

114

Implementing the High-Level UI Using Adaptive User Interface Technology 115 Design 115

Contents

vii

Customization

117 117

Property Loading and Skin Customization Image Usage and Support 117

Compressed Images Compared With Uncompressed Images ROMized Images Compared With File System Images Storing Image Resources in the File System Storing Image Resources in the ROM RAW Format Platform Specification Support for Virtual Keyboard Porting Steps 12. 121 125 121 119 120 118 118

118

Implementing the High-Level UI Using Platform Components Overview 125 126

Component Dependencies Porting Steps Testing 13. 127 130

Porting the Event Processing Service Event System

133

134 136 136

Submitting Native Events Complete the Event Fields Locking 137

Setting the MAX_EVENTS Constant Types of Event Systems Normal Mode Slave Mode 138 138

138

140 142 145

Choosing Normal or Slave Mode 14.

Application Management with the Java Platform Native AMS 146

viii

Architecture and Design Guide December 2008

AMS Functionality

146 149

External Interactions With AMS MIDlet Suite Attributes 151

Extended MIDlet Attributes Inter-MIDlet Communication

152

153 154

Using the Pipe Communication Protocol Downloading Dynamic Components 156

Configuring the AMS for Dynamic Components Defining the Location for Dynamic Content Security Restrictions Support for Clamshell Devices Porting and Customizing 159 159 160 158 158

156 157

Strategies for Porting the AMS

Strategies for Customizing the AMS Things to Consider AMS UI Implementation Configuration Examples 160 161 162 162

Default Implementation Custom Installer 163

Default Application Manager Custom Application Manager 15. MIDlet Auto Invocation Design 168 169 170 167

164 165

Design Overview

Push Connection States

Design Rationale, Notes, and Considerations Porting 172 172

171

Protocols

Contents

ix

Listening for Incoming Data Message Buffering User Interaction 173

173

174 174 174

MIDlet Concurrency

Adding Network Protocols for Push 177 178

16.

Runtime Security

Design Considerations

Native VM Startup Code and MIDlet Suite Loader Class Loader Security Token Using the Service 178 179 179 179

178

Classes Protected by Security Tokens Classes Used by Internal MIDlets 17. Permission Management Design Overview 182 182 181 180

Security Handler Permissions 182

Design Rationale, Notes, and Considerations Policy Configuration Implementations New Permissions

184

184 185

185 185

Adding a New Permission 187

New Domains

Adding a New Domain

187 187 188 189

Using Permissions for Internal MIDlets

Finding the Status of a Security Certificate 18.

Native Resource Management for Multitasking

Architecture and Design Guide December 2008

Fixed Resource Policy Open Resource Policy Porting 19. 191

189 190

Porting the Networking Subsystem

193 194

Generic Connection Framework and Protocol Implementations Porting the Networking Subsystem General Porting Considerations Porting Considerations for HTTP HTTP Requests Using Proxies 195 197 197 197 198 198

HTTP1.1 Persistent Connections Porting Considerations for HTTPS Porting HTTPS 198

Using the Java Wireless Client Software SSL Implementations Porting Considerations for Server Socket Network Monitoring References 20. 205 207 199 199

199

Porting the User Message Bundle Service Design 207 208 208 209

Access Module Behavior Module

Decoder-Encoder Component

Design Rationale, Notes, and Considerations Porting

209

209 Adding Additional Message Strings 210 210 210

Supporting a New Locale

Supplying Locale-Specific Strings 211

Adding a Character Encoding

Contents

xi

Changing the Default Screen Orientation Customizing the Screen Display 21. Games 215 213

213

Engineering and Device Requirements Design 216 217

215

Sprites and Tiled Layers Example Sprite 217

Example Tiled Layer

218 219 220 220

Layer Manager Component Game Canvas Component

Design Rationale, Notes, and Considerations Porting 220 221 221

Porting GameCanvas

Porting Sprite and TiledLayer A. Performance Notes 223 223 223

Application Startup Time

Measuring Startup Time

Handling Startup Time Variance Starting an Application 225

224

Optimizing a MIDlet for Improved Application Startup Time Optimizing the System for Improved Application Startup Time Minimizing the Static Initialization of System Classes 227

226 227

Controlling the JIT Compiler and Ahead-of-Time Compilation Giving the VM Hints 228 230

228

Disabling the Class Verifier Caching Images

230 231

Caching JAR File Entries

xii

Architecture and Design Guide December 2008

Runtime Performance

232 232 233 233

Performance Metrics

Profiling the System

Runtime Optimizations Caching Indexing Buffering Memory Footprint

233 234 234 235 235 236 236 237

Measuring Footprint

Minimizing Static and Dynamic Footprint Heap Capacity for the Java Platform

Minimizing the Space Used by AOT and JIT Compilation 238

Minimizing Full Garbage Collections at Startup Summary Glossary Index 238 241

245

Contents

xiii

xiv

Architecture and Design Guide December 2008

Figures

FIGURE 1-1 FIGURE 1-2 FIGURE 1-3 FIGURE 1-4 FIGURE 1-5 FIGURE 1-6 FIGURE 4-1 FIGURE 6-1 FIGURE 8-1 FIGURE 10-1 FIGURE 10-2 FIGURE 10-3 FIGURE 10-4 FIGURE 10-5 FIGURE 10-6 FIGURE 10-7 FIGURE 10-8 FIGURE 10-9 FIGURE 10-10 FIGURE 10-11

Overall Architecture

2 5 6

Component Implementation

Modular Architecture Supporting Multiple Implementations Component Relationships and Flow Control Possible APIs in Subsystems and Services Porting Points 8 Configurator Work Flow for Constants and Properties RMS Subsystem Components 42 67 25 7 8

Five PCSL Networking Implementations Subsystem Interactions 80

drawLine Method Through Its C Call

82 83 85

Functions That Update Property Values and Functions Providing Data Components of the Low-Level Graphics and Images Service Subsystem Decoder Architecture 87 91

drawLine Method Through Its C Call Graphics Class Coordinate System Drawing a Line 95 94

Drawing Compared With Filling a Rectangle Ellipse 96

96

Circle 97

xv

FIGURE 10-12 FIGURE 10-13 FIGURE 10-14 FIGURE 10-15 FIGURE 10-16 FIGURE 10-17 FIGURE 12-1 FIGURE 12-2 FIGURE 13-1 FIGURE 13-2 FIGURE 13-3 FIGURE 14-1 FIGURE 14-2 FIGURE 14-3 FIGURE 14-4 FIGURE 14-5 FIGURE 14-6 FIGURE 15-1 FIGURE 20-1 FIGURE 21-1 FIGURE 21-2 FIGURE 21-3 FIGURE 21-4 FIGURE 21-5

0, 90, and -90 Degrees on a Circle Boxed Ellipse 98

97

45 and -120 Degrees on a Circle 45 and -120 Degrees on an Ellipse

99 99 99

Boxed Circle and Ellipse, With a 45 Degree Angle Drawing a Rectangle With Rounded Corners 100

Major Elements of the High-Level UI in a Java Wireless Client Software Port High-Level GUI Components and Dependencies Event Queue Components and Interactions 135 139 142 127

126

CLDC HotSpot Implementation Running in Normal Mode CLDC HotSpot Implementation Running in Slave Mode AMS Architecture on a Device 149

AMS Using Java Wireless Client Software Default Implementations AMS Using Custom Installer 163

163

AMS With Custom Installer and Custom Suite Storage Implementation AMS With Default Java Wireless Client Software Application Manager AMS With Custom Native Application Manager Push Connections State Transitions 171 208 166

164 165

User Message Bundle Service Components and Interactions Interactions of Subsystems Source Image for a Sprite 215 218 218 218

Example Animation Sequence Source Image for a Set of Tiles Tiled Layer 219

xvi

Architecture and Design Guide December 2008

Tables

TABLE 1-1 TABLE 1-2 TABLE 7-1 TABLE 7-2 TABLE 8-1 TABLE 10-1 TABLE 14-1 TABLE 14-2 TABLE 14-3 TABLE 15-1 TABLE 17-1 TABLE 17-2 TABLE 19-1 TABLE 19-2 TABLE 19-3 TABLE 19-4 TABLE A-1

Java Wireless Client Software Services

3 4 48

Java Wireless Client Software Subsystems

Java Wireless Client Software Subsystems and Libraries Native File Library Prefix Examples 55 67

PCSL Technologies File System Locations Low-Level Graphics Constants 93 147

Application Management Functionality

Additional Test and Development Functionality

147 149

AMS Interaction With Java Wireless Client Software Systems Auto Invocation Subsystem Interactions Permission Level 183 168

Java Technology for the Wireless Industry Permission Levels Networking Subsystem Protocols 193 195

184

Common Features Used by Java Classes Network Monitor Hooks (1) Network Monitor Hooks (2) 200 203

Initial Steps in the Procedure for Starting a MIDlet

225

xvii

xviii

Architecture and Design Guide December 2008

Code Examples

CODE EXAMPLE 4-1 CODE EXAMPLE 4-2 CODE EXAMPLE 4-3 CODE EXAMPLE 5-1 CODE EXAMPLE 5-2 CODE EXAMPLE 5-3 CODE EXAMPLE 5-4 CODE EXAMPLE 5-5 CODE EXAMPLE 5-6

Adding a New Element to a Property File 28 constant_class Element in Constants Input File 30 constant Element in constant_class Element of Input File MID_CONTROL_ARG Syntax 35 Testing a Log Messages Severity Against REPORT_LEVEL Using the if Statement Tests a Messages Severity Adding a Channel Definition for a Bluetooth Module 37 37 38 36 30

Using an if Statement to Test if TRACE_ENABLED is true if Statement for ASSERT_ENABLED 39 109

CODE EXAMPLE 10-1 midpLCDUIShowBacklight Interface

CODE EXAMPLE 10-2 midpLCDUIShowBacklight Interface Without Backlight Control CODE EXAMPLE 10-3 Starting Vibration CODE EXAMPLE 10-4 Stopping Vibration 111 111

110

CODE EXAMPLE 12-1 runMidlet Utility Syntax 130 CODE EXAMPLE 13-1 Code Completing a MidpEvent Data Structure CODE EXAMPLE 14-1 JAD file descriptors 152 152 155 155 155 136

CODE EXAMPLE 14-2 Extended MIDlet attributes

CODE EXAMPLE 14-3 MIDlet server-side connection

CODE EXAMPLE 14-4 Client MIDlet connects to server-side MIDlet

CODE EXAMPLE 14-5 Transferring data between server-side and client MIDlets

xix

CODE EXAMPLE 14-6 Closing the connection between MIDlets CODE EXAMPLE 14-7 The installComponent interface CODE EXAMPLE 17-1 Permission Extension. 186 213 158

155

CODE EXAMPLE 20-1 Setting the Screen Orientation

xx

Architecture and Design Guide December 2008

Preface
This Guide provides information that is useful to consider before and during a port of the Sun JavaTM Wireless Client (SJWC) software, version 2.2, to your mobile device. For more information on the steps and procedures you should follow to port the SJWC software, see the Sun Java Wireless Client Software Porting Users Guide.

Before You Read This Book


To fully use the information in this document, you must have thorough knowledge of the topics discussed in these documents:

JSR 139 Connected Limited Device Configuration 1.1 JSR 118 Mobile Information Device Profile 2.0 JSR 185 Java Technology for the Wireless Industry JSR 248 Mobile Service Architecture CLDC HotSpot Implementation Porting Guide Skin Authors Guide to Adaptive User Interface Technology JSR 75 PDA Optional Packages for the J2ME Platform JSR 82 Java APIs for Bluetooth JSR 120 Short Message Service API JSR 135 Mobile Media API JSR 172 J2ME Web Services JSR 177 Security and Trust Services API for J2ME JSR 179 Location API for J2ME

Preface

xxi

JSR 180 SIP API for J2ME JSR 205 Wireless Messaging API 2.0 JSR 211 Content Handler API JSR 226 Scalable 2D Vector Graphics API for J2ME JSR 234 Advanced Multimedia Supplements JSR 238 Mobile Internationalization API JSR 239 Java Binding for the OpenGL ES API JSR 256 Mobile Sensor API JSR 280 XML API for Java ME

How This Book Is Organized


This book contains the following chapters and appendices: Chapter 1 is a basic overview of the Java Wireless Client software and how it works. Chapter 2 is an overview of the porting process. This chapter provides a high-level strategy for porting the Java Wireless Client software to your device. Chapter 3 lists the hardware and software required to successfully port the software, and describes some limitations of the software. Chapter 4 documents how to manage properties and constants in Java Wireless Client software with a tool called the configurator. Chapter 5 documents the design and porting of the logging and tracing subsystem of the Java Wireless Client software. Chapter 6 documents the design of and strategies for porting the record management (RMS) subsystem. Chapter 7 documents how the source base is organized and the conventions used for naming native files. Chapter 8 documents the Portable Common Services Library (PCSL) and its use in the porting process. Chapter 9 documents how to implement graphics, images, and fonts using PutPixel technology. Chapter 10 documents the low-level graphics and images service.

xxii

Architecture and Design Guide December 2008

Chapter 11 documents how to port the high-level user interface using Adaptive User Interface Technology software (AUI Technology software). Chapter 12 documents how to port the high-level user interface using platform components. Chapter 13 documents the design and porting of the event processing service. Chapter 14 documents the design and porting of the application management service (AMS) subsystem. Chapter 15 documents the design and porting of the MIDlet auto invocation subsystem of the Java Wireless Client software. Chapter 16 documents the design and use of the runtime security service. Chapter 17 documents how the runtime security service uses permission management. Chapter 18 documents native resource management policies used for multitasking. Chapter 19 documents the design and porting of the networking subsystem of the Java Wireless Client software. Chapter 20 documents the design and porting of the user message bundle subsystem used for internationalizing the Java Wireless Client software. Chapter 21 documents the design and porting of the game subsystem of the Java Wireless Client software. Appendix A describes how to analyze and tune the performance of the Java Wireless Client software.

Using Operating System Commands


This document does not contain information on basic UNIX operating system or Microsoft Windows commands and procedures such as opening a terminal window, changing directories, and setting environment variables. See the software documentation that you received with your system for this information.

Preface

xxiii

Typographic Conventions
Typeface Meaning Examples

AaBbCc123

The names of commands, files, and directories; on-screen computer output What you type, when contrasted with on-screen computer output Book titles, new words or terms, words to be emphasized Command-line variable; replace with a real name or value

Edit your .login file. Use ls -a to list all files. % You have mail. % su Password: Read Chapter 6 in the Users Guide. These are called class options. You must be superuser to do this. To delete a file, type rm filename.

AaBbCc123

AaBbCc123

Shell Prompts
Shell Prompt

C shell

Related Documentation
The following documentation is included with this release:
TABLE P-1 Application Title

All Building Porting Issues and Overview

Release Notes Build Guide Architecture and Design Guide

xxiv

Architecture and Design Guide December 2008

TABLE P-1 Application Title

Porting Procedures and Guidelines Running SJWC Software and Using Tools Multitasking Integration and Policies Using Adaptive User Interface Technology (skins) Viewing reference documentation created by the Javadoc tool Viewing reference documentation created by the Doxygen tool

Porting Guide Tools Guide Multitasking Guide Skin Authors Guide to Adaptive User Interface Technology Java API Reference Native API Reference

In addition, you might find the following documentation helpful:

The Java Language Specification (Java Series), Second Edition by James Gosling, Bill Joy, Guy Steele and Gilad Bracha. Addison-Wesley, 2000, http://java.sun.com/docs/books/jls/index.html. The Java Specification Request (JSR), (J2ME Connected, Limited Device Configuration) at http://jcp.org/jsr/detail/30.jsp (JSR 30) Mobile Information Device Profile 2.0, at http://jcp.org/jsr/detail/118.jsp (JSR 118) Java Technology for the Wireless Industry, at http://jcp.org/jsr/detail/185.jsp (JSR 185) A full list of JSRs for the Java Platform, Micro Edition (Java ME platform), available at http://jcp.org/jsr/tech/j2me.jsp KVM Debug Wire Protocol (KDWP) Specification, Sun Microsystems, Inc., available as part of the CLDC (Connected Limited Device Configuration) download package.

Accessing Sun Documentation Online


The Source for Java Developers web site enables you to access Java platform technical documentation on the web at http://java.sun.com/reference/docs/index.html.

Preface

xxv

Sun Welcomes Your Comments


We are interested in improving our documentation and welcome your comments and suggestions. Provide feedback to Sun at http://java.sun.com/docs/forms/sendusmail.html.

xxvi

Architecture and Design Guide December 2008

Software Overview
Java Wireless Client software is a high-performance Java ME platform stack for mobile devices. Java Wireless Client software shortens the porting and integration effort with the following features:

It uses a modular architecture that supports multiple implementations within each functional area (such as storage, networking, user interface, and so on). It minimizes platform-specific code to achieve portability. Minimizing platformspecific code makes it easier to port Java Wireless Client software to a broad range of devices. You can pick and choose the features you want on your device and implement them as modules. This flexibility facilitates customizing your devices features and functions for your customers.

Specifications and APIs


Java Wireless Client software supports many components of Mobile Service Architecture (MSA) (JSR 248). MSA is a comprehensive platform based on CLDC and MIDP. Here is a complete list of the APIs encompassed by Java Wireless Client software:

JSR 139 CLDC 1.1 JSR 118 MIDP 2.1 JSR 75 Personal Information Management (PIM) and FileConnection APIs JSR 82 Bluetooth and OBEX APIs JSR 120 Wireless Messaging API (WMA) 1.0 JSR 135 Mobile Media API (MMAPI) 1.1 JSR 172 Web Services JSR 177 Security and Trust Services
Chapter 1 Software Overview 1

JSR 179 Location JSR 180 Session Initiation Protocol (SIP) JSR 205 Wireless Messaging API (WMA) 2.0 JSR 211 Content Handler API (CHAPI) JSR 226 Scalable 2D Vector Graphics (SVG) JSR 234 Advanced Multimedia Supplements JSR 238 Mobile Internationalization JSR 239 Java Bindings for OpenGLTM Embedded Subsets JSR 256 Mobile Sensors API JSR 280 XML API for Java ME

In addition, Java Wireless Client software also supports JSR 239 OpenGL ES, an optional API that is not part of MSA. Consult the Java Community Process (JCP) program web site, http://jcp.org/, for more information on any of these specifications.

Architecture
In very broad terms, the architecture of Java Wireless Client software looks like this:
FIGURE 1-1

Overall Architecture

Java Wireless Client software is everything that lies between the OS and applications. (The OS layer sits directly below the JavaCall layer). The Java Wireless Client software includes:

The JavaCall layer distills the platform requirements of the entire platform down to a single set of functions that must be ported. All porting is done at the same layer, and the functions are consistently named and well documented. Portable Common Services Library (PCSL) is a layer of low-layer services that are used by CLDC, MIDP, and some of the optional APIs.

Architecture and Design Guide December 2008

Note In

FIGURE 1-1, PCSL is a component within the MIDP/CLDC block.

Connected, Limited Device Configuration (CLDC) is an implementation of JSR 139. It includes a virtual machine and core Java ME application APIs. Mobile Information Device Profile (MIDP) is an implementation of JSR 118. Optional package JSRs provide optional functionality supported under the MSA 248 Specification. For a complete list of supported optional packages, see Specifications and APIs on page 1. The Abstraction Layer is a set of functionality that allows all optional packages to talk to MIDP/CLDC through a common set of interfaces.

You dont have to do any porting on PCSL, CLDC, MIDP, and the optional APIs, because they are internally ported to the JavaCall API already. To port to a new platform, all you have to do is the implement the JavaCall API functions to perform the actual work in the underlying OS. For new development, the JavaCall API is also recommended. For step-by-step instructions on porting to your platform, see the Sun Java Wireless Client Porting Users Guide.

MIDP Services and Subsystems


The MIDP component is composed of a modular set of services and subsystems. Services provide functionality that all subsystems use, such as logging. Subsystems are high-level functional blocks, such as the user interface and networking. The following table lists the Sun Java Wireless Client Software services.
TABLE 1-1 Service

Java Wireless Client Software Services


Description

Logging and tracing

Provides a way to collect information that developers can use during a porting effort or at a later stage of product development. Provides a basic set of memory management routines, such as allocating and freeing memory, that all other subsystems use. Provides support for localization.

Native memory management User message bundles

Chapter 1

Software Overview

TABLE 1-1 Service

Java Wireless Client Software Services (Continued)


Description

Event processing Security Configuration

Collects and dispatches system events such as user interaction, networking, push events, I/O, and so on. Determines trust in (and permissions for) MIDlet suites and protects APIs. Maintains constants and properties so that they have the same definition in both the Java platform layer (Java layer) and the native platform layer. Also compiles in property values to avoid initialization overhead. See Chapter 4 for more information.

The following table lists the Java Wireless Client software subsystems.
TABLE 1-2 Subsystem

Java Wireless Client Software Subsystems


Description

Application Management Software (AMS) and over-the-air (OTA) provisioning Networking Push Record Management System (RMS)

Finds MIDlet suites, manages and executes them on the device Sends and receives data Receives a communication initiated by an external entity Provides record-oriented persistent storage, enforces a permission policy for accessing the records, and enforces size constraints on the record store Mobile Service Architecture (MSA) compliant optional APIs. These optional APIs are described in the Optional Packages Porting Guide. Interacts with the end user of a device through high-level and low-level userinterface components and supports games

Optional APIs

User Interface (LCDUI)

Architecture and Design Guide December 2008

Components
Java Wireless Client software subsystems and services are made up of one or more components called libraries. A library is a unit with an explicitly declared exported interface. One or more implementations of the interface can exist. Each implementation declares dependencies on other libraries whose interfaces it imports. A library can be implemented partially in the Java programming language and partially in native code. No code is shared between alternative implementations of the same exported interface. Shared code resides in a separate library, ensuring that the interface between the shared and non-shared portion is explicitly declared. This separation makes it easy to reuse shared code in new implementations. Platform-independent code and platform-specific code are contained in separate libraries. The interface between the platform-independent and platform-dependent libraries constitutes the porting interface as shown in FIGURE 1-2.
FIGURE 1-2

Component Implementation

Subsystem or service Platform-independent libraries

Porting API

Platform-dependent libraries

Each library can have multiple implementations, each tailored to a different type of device. This architecture makes Java Wireless Client software easier to port and makes it easier to optimize performance. FIGURE 1-3 describes this architecture.

Chapter 1

Software Overview

FIGURE 1-3

Modular Architecture Supporting Multiple Implementations

Application (MIDlet)

Libraries: Multiple implementations of Java Wireless Client software Target platform

When you port the Java Wireless Client software, you choose the set of libraries most suited to your system. For each library, you can either choose one of existing implementations or provide your own implementation of the librarys exported interface. Because libraries are bound at compile time, this approach has no impact on runtime performance. The build system sets aside unused libraries and implementations so the systems footprint on the device is not increased.

Control Flow
The following diagram illustrates the relationship between the different Java Wireless Client software components. It highlights how control flows between the different components.

Architecture and Design Guide December 2008

FIGURE 1-4

Component Relationships and Flow Control

Application

MIDP Event management code Platform-specific MIDP code Underlying OS/JavaCall API Hardware CLDC PCSL Platform-specific CLDC code Platform-independent code

Device Interactions
This section describes how Java Wireless Client software fits into the platform environment. It provides a general idea of what the porting points (areas of interaction between Java Wireless Client software and the device) are. The porting points are made possible by the APIs shown in FIGURE 1-2 and FIGURE 1-5.
FIGURE 1-5

Possible APIs in Subsystems and Services Application Public APIs

Subsystem or service libraries

Subsystem or service libraries Porting APIs Internal APIs

Target platform

Chapter 1

Software Overview

FIGURE 1-6 shows a number of porting points. For example, one porting point binds Java Wireless Client software low-level graphics primitives with the graphics library of your device. Another porting point manages applications, such as Java Wireless Client software, using native code to provide Over-the-Air (OTA) provisioning required by the MIDP 2.0 Specification.
FIGURE 1-6

Porting Points Speaker

Application management LEDs

Java Wireless Client software Persistent storage Networking

Graphical display

User interaction

Architecture and Design Guide December 2008

Porting Overview
This chapter is a high-level overview of the porting process. It breaks the porting process into a series of discrete, general steps and provides a description and rationale for each step.

Note The Sun Java Wireless Client Porting Users Guide provides a step-by-step
process for porting the Sun Java Wireless Client software to a standalone or handheld device. For more information, see that guide. To port the Sun Java Wireless Client software, follow these general steps: 1. Build for one of the reference platforms. This verifies that you have most of the right tools available and understand at a high level how the build works. You get to practice building with a fully functional set of source code before starting the port to your own device. Consult the Build Guide for instructions on building Java Wireless Client software. 2. Run TCKs on the reference platform build. Configuring and running TCKs is not a simple task, so doing this on a reference platform build gives you some practice on a working build before you start porting to your own device. 3. Set up your device development system. You might need another compiler to build for your device. In addition, you need to understand or create mechanisms for moving executables to your device, running them, and interacting with them. 4. Port the Sun Java Wireless Client software (and supporting optional packages) using the JavaCall API. As you complete each component, run tests to verify your implementation. For more information and the specific steps to take to complete your port, see Sun Java Wireless Client Porting Users Guide.

Chapter 2

Porting Overview

Build the Software on the Reference Platform


The first step in the porting process is to build and understand a Java Wireless Client software reference platform port. By building a source base that is known to build correctly and to run on a specific platform, you can become familiar with the source base and the process required to build the software. Because you can observe its behavior in a debugger while you work on your port, the reference port is extremely helpful when you start to port the software to your device.

Note Be sure to document the process as you go so that it can be replicated by


other developers in your organization. The Build Guide describes how to build a reference platform port.

Run TCKs on the Reference Port


To demonstrate that your port conforms to the relevant specifications and is compatible with other versions of the software, you must run the applicable Technology Compatibility Kits (TCKs) on the finished product. The task of configuring the TCKs and successfully running the tests is not a simple one. For that reason, run the TCK on the reference port before you attempt to run it on your ported version of the software. By first running the TCK on the reference implementation, you know that all the tests run successfully and that no tests fail. If any tests fail, it is probably because you configured the test environment incorrectly. After you successfully configure and run the TCK on the reference port, it is much easier to run the test suite on your ported version of the software. Be sure to document the process as you go so that it can be replicated by other developers in your organization. You must run the current applicable TCK for each portion of the Java Wireless Client software that you port.

10

Architecture and Design Guide December 2008

Note As delivered, the Java Wireless Client software does not include all of the
software components necessary to pass all of the TCKs. For multimedia (both MMAPI and AMMS), 3D graphics, and OpenGL ES in particular, you must integrate third-party components before the corresponding TCK tests are passed.

Set Up and Configure Your Device Development Environment


To be able to port efficiently, you must set up your development environment so that you can download programs and data into your device and receive debugging information from the device. Specifically, your environment must enable you to do the following tasks:

Build the system Get the executable code onto the device Run the code on the device Understand what happens when the code runs Load files or data onto the device Read files or data from the device

Requirements differ depending on your development environment. For example, if you develop your port on a software emulator that runs on a computer system, you might be able to accomplish this by simply copying files into the emulator and using printf statements to write to the console. On the other hand, if you develop on a simulator board, a development board, or directly on the device, this can be more complicated because it has no console. However, a serial port through which (with extra work) you can get output might be available.

Chapter 2

Porting Overview

11

Port the JavaCall API


The JavaCall API provides a set of classes and methods that allow you to port components in the Java Wireless Client software quickly and easily. The Java ME programming language functions in each module - CLDC, PCSL, MIDP, and the optional package APIs - have already been written to their corresponding JavaCall functions. Your job is to implement the code that ties the bottom of the JavaCall layer to the native OS. You do this by implementing the relevant JavaCall functions on a step-bystep basis, as described in the Sun Java Wireless Client Porting Users Guide.

Functions and Naming


JavaCall API functions are grouped by purpose into modules. Each module is represented by one or more header files which define the functions in the module. The JavaCall API contains two types of functions:

javacall_ functions perform some work in the native OS, usually on behalf of a MIDlet application. When you port to your own device, you must implement the body of these functions. javanotify_ functions are called by the native OS when important things happen, like key presses, incoming messages, or other events. When you port to your own device, you must write code that will call these functions at the appropriate times.

A module contains some mix of javacall_ functions and javanotify_ functions. For example, javacall/interface/jsr120_wma/javacall_sms.h defines a handful of functions related to sending and receiving text messages. It includes a javacall_sms_send() function thatsends a text message and a javanotify_incoming_sms() function that is called when a message is received. Your job is to implement the javacall_sms_send() function to use the underlying OS services to send a text message. In addition, you must write OS code that calls javanotify_incoming_sms() when a message is received from the network. The JavaCall API functions are also classified as mandatory or optional. Mandatory functions must be implemented for the software to work. Optional functions have default implementations, but you might be able to provide better performance or functionality by implementing them.

12

Architecture and Design Guide December 2008

The Java Wireless Client software documentation includes the JavaCall API Reference, which is an extremely useful way to view detailed information about the JavaCall API.

Directory Structure
The JavaCall API is distributed in the javacall and javacall-com subdirectories under the main Java Wireless Client software directory. These subdirectories contain the header files that define the JavaCall API as well as a full implementation for Windows. javacall and javacall-com have similar internal structures. The JavaCall API header files are contained in javacall/interface and javacallcom/interface. Each header file contains a set of related functions. The header files for MIDP live in subdirectories of javacall/interface/midp. Header files for optional APIs are contained in directories corresponding to their defining JSR. For example, the JavaCall API for Bluetooth functionality is contained in javacall-com/interface/jsr82_bt. The header files used by MIDP, and some optional packages at the same time, reside in javacall/interface/common. Optional APIs might have more than one header file that defines the corresponding JavaCall API. For example, the PIM and FileConnection APIs defined by JSR 75 are represented by these headers:
javacall-com/interface/jsr75_pim_fc/javacall_pim.h javacall-com/interface/jsr75_pim_fc/javacall_fileconnection.h

The JavaCall API includes an implementation for Windows in javacall/implementation/win32_emul and javacallcom/implementation/win32_emul. The source files are organized in a structure similar to the structure for the header files. For example, javacall/implementation/win32_emul/midp/lcd.c is the implementation of the JavaCall API defined in javacall/interface/midp/javacall_lcd.h.

Understanding the Event Module


The JavaCall APIs Event module deserves special mention. Unlike many of the other modules, it does not directly implement some higher-level application API functionality.

Chapter 2

Porting Overview

13

Instead, the Events module is used for communication between your native, OSlevel implementation and the Java platform. In its simplest form, it is a message queue for exchanging messages between native threads and the Java platform thread. One thread is dedicated to the Java platform. The virtual machine runs in this thread, and your implementation of the JavaCall API will make native OS calls to do the works of applications running in the Java platform. At the same time, one or more native threads will find out about important events like key presses, incoming messages, requests to pause or resume the Java platform, and so on. The code running in native threads needs a way to notify the Java platform about these important events. As you learned in the last section, you write the native code that calls the javanotify_ functions as needed. Internally, the JavaCall API uses the Event module to communicate notifications from the native thread to the Java platform thread. Part of your job is to port the Event module so that when your native code calls javanotify_ functions, the Java platform thread receives the corresponding notifications. For example, when an application sends a text message, eventually the Java platform calls javacall_sms_send(). Your implementation of javacall_sms_send() uses OS or device functions to queue a message for sending. The OS sends the message, probably in its own thread. When the sending is finished, your native code calls javanotify_sms_send_completed(). The JavaCall API takes care of using the Event module to pass a message back to the Java platform thread. For more informaton on the Event module, see Chapter 13.

The JavaCall Porting Process


As described in the Sun Java Wireless Client Porting Users Guide, the recommended order to port the Java Wireless Client JavaCall subsystems is: 1. Logging Facility 2. Memory System 3. Time and Timers 4. Filesystem APIs 5. LCD (Display) APIs 6. Event Handling 7. Keypress Events 8. Lifecycle Events 9. Milestone One: Run a ROMized interactive MIDlet

14

Architecture and Design Guide December 2008

10. Basic Networking and Socket Communication 11. Advanced Networking and Socket Commun ication 12. Font System 13. Annunciator 14. Predictive Text Input Support (optional) 15. Native Image Decoding (optional) 16. Implement Optional APIs, including some or all of the following:

JSR 75 File Connection and Personal Information Management APIs JSR 82 Bluetooth API JSR 120 Wireless Messaging API 1.0 JSR 135 Mobile Media API JSR 177 Security and Trust Services API JSR 179 Location and Landmark Store API JSR 205 Wireless Messaging API 2.0 JSR 211 Content Handler API JSR 234 Advanced Multimedia Supplements JSR 256 Mobile Sensor API

17. Milestone Two: Run TCKs and Test Your Completed Port

Chapter 2

Porting Overview

15

16

Architecture and Design Guide December 2008

Hardware and Software Requirements and Constraints


You can build Java Wireless Client software on Microsoft Windows or Linux. Get started with a self-hosted build, which means you build, run, and debug the software on the same machine. This is a great way to get acquainted with the build system and structure of Java Wireless Client software. Later, you cross-compile, which is building on one platform but running on another. For example, you could use a desktop Linux machine to build executables for the ARM-based Texas Instruments OMAP730 development board. Java Wireless Client software contains reference ports to the Microsoft Windows platform and the Texas Instruments OMAP730 development board. The host development environment for building the OMAP730 implementation is a Linux system running on x86 hardware. This chapter lists some requirements and constraints of the reference ports and the development environment. The Release Notes contain additional information. The source code makes some assumptions about the capabilities of the development environment and the ports target device. In addition, because Java Wireless Client software is designed for small devices, it has resource constraints that this chapter describes. In addition to the Java Wireless Client software source distribution, the CLDC HotSpot Implementation, Version 2.0 source distribution is required to create a complete Java Technology for the Wireless Industry software implementation for the target device.

Chapter 3

Hardware and Software Requirements and Constraints

17

Data-Type Assumptions
The native code in the Java Wireless Client software expects some data types to be specific sizes, as follows:

int - 32 bits short - 16 bits char - 8 bits signed long - 32 bits sizeof(void*) = sizeof(int)

Native code might behave unpredictably if the platform does not satisfy these expectations.

Resource Limitations
Java Wireless Client software is intended to run on resource-constrained devices. Unlike a desktop or server system, available memory and persistent storage are limited. Some devices quit when excess native resources are requested. This section lists areas in which you can limit resources in the initial phase of your port. The section contains possibilities, not an exhaustive list, of all the resources Java Wireless Client software could use or consume. Consult the MIDP specification for details.

Native Stack Size


The CLDC HotSpot implementation uses a single stack (a primordial stack) to run native code. To conserve runtime memory, try to define the stack size to match your target platform. A Java Wireless Client software binary is a normal executable produced by your target platforms tool chain just like other native binaries. Java Wireless Client software uses the default C stack provided by the tool chain as its primordial stack. Whether you can change the default stack size, and how you change it, depends on your build tools and your target devices operating system. See your tool and device documentation for information.

18

Architecture and Design Guide December 2008

If you can change the stack size, its minimum size depends on a number of factors, such as the type and complexity of Java ME technology applications that your port will run, and the stack usage of your devices native functions. A stack size that is too small can lead to stack corruptions.

Tip On the ARM platform, typical game MIDlets require between 5 kilobytes and 6 kilobytes of primordial stack to run reliably. Adding a safety margin of 2 kilobytes makes the minimum stack size 8 kilobytes.

AMS Resource Limitations


You can set the following values used by the application management system:

Maximum size of a Java Archive file (JAR file). Note that Java Technology for the Wireless Industry specifies 64 kilobytes as the lowest this limit can be set. Maximum length of an attribute in a Java Application Descriptor file (JAD file). Maximum size of a JAD file. The Java Technology for the Wireless Industry minimum is not specified. Maximum length of a MIDlet suites name. Maximum length of a file name.

RMS Resource Limitations


In brief, the current limitations are as follows:

The minimum RMS data size that should be supported on an explicit suite request is 64 kilobytes (according to MSA specification 1.0). The maximum RMS data size per suite is 200,000 bytes. The maximum suite storage size for all installed MIDlet suites and their RMS data is 1,000,000 bytes.

Java Wireless Client software limits suite storage size, which is the common space available for MIDlet suites and their record stores. The maximum RMS record store size is separately limited by the RMS implementation.

Chapter 3

Hardware and Software Requirements and Constraints

19

The system.jam_space Property


If the system.jam_space property is set, it is used as the maximum space for MIDlet suites and their record stores. For JavaCall builds, this property is defined in the following location: javacall-com/configuration/sjwc/win32_emul/properties.xml For non-JavaCall builds, the system.jam_space property is defined here, where platform is the platform on which you are building: midp/src/configuration/configuration_xml/platform/properties.xml The default value for system.jam_space is 1,000,000 bytes.

The DEFAULT_TOTAL_SPACE Property


If system.jam_space is not defined, then DEFAULT_TOTAL_SPACE is used. This value is defined here: midp/src/core/storage/reference/native/midpStorage.c The default value for DEFAULT_TOTAL_SPACE is 4 megabytes.

The STORAGE_SUITE_LIMIT Property


The maximum size for record stores per MIDlet suite is defined by the constant STORAGE_SUITE_LIMIT, which can be different for each platform. This constant is defined here: midp/src/configuration/configuration_xml/platform/constants.xml The default value is 200,000 bytes. The amount of additional room available for a record store to grow is returned by RecordStore.getSizeAvailable(). This value is limited as follows: min(INT_MAX, realAvailableSize) This is important when removable media is used for storing the RMS files.

20

Architecture and Design Guide December 2008

Networking Resource Limitations


The networking subsystem has a maximum number of HTTP connections that can be open at any one time.

Graphics Resource Limitations


The low-level graphics and images subsystem has the following limitations:

Maximum image height and width of a graphic or image, in pixels Maximum size of an image, in pixels

Other Resources
The limits for many resource types are set in XML files in midp/src/configuration/configuration_xml. Inside a directory corresponding to your target platform, youll find XML files that contain limits for networking, memory, images, and other resources. To change resource limits, edit the appropriate file and change the value. Then build the Java Wireless Client software again. For full details on how these values are incorporated into the build, see Chapter 4.

Chapter 3

Hardware and Software Requirements and Constraints

21

22

Architecture and Design Guide December 2008

401

Managing Properties and Constants


You manage properties and constants in Java Wireless Client software with a tool called the Configurator. This chapter covers the tools design, how to use it to manage properties and constant values, and how to use its output.

Note You do not port the Configurator.

Introduction
The Configurator is a development tool that runs on the desktop, not on the device. The Configurator maintains properties and constants. It assures that they are defined the same in both the Java layer and the native platform layer. Any Java Wireless Client software service or subsystem that calls the System.getProperty or Configuration.getProperty methods depends on the Configurator. Any subsystem that uses at least one constant value in both the Java platform and native layers also depends on the Configurator. The Configurator is is also used to manage localized strings. Each locale has an XML file that contains localized strings. These XML files are processed by the Configurator at build time, generating C and Java programming language files and providing localized strings at runtime. The build system automatically runs the Configurator.

Chapter 4

Managing Properties and Constants

23

Design
Two of Java Wireless Client softwares goals are seemingly in conflict: It must be highly configurable and must have a minimal runtime footprint. The Configurator tool reconciles these goals by providing the ability to set the property and constant values for a particular platform, and then generate only those values. The Configurator provides the following advantages:

Flexibility The Configurator is able to process input files on a subsystem-bysubsystem (or service-by-service) basis. Maintainability The Configurator uses a number of files that fully describe Java Wireless Client softwares properties, constants, and localized string resources. The input files of the Configurator are divided by content type, platform dependence, and functional principles. The input files are maintained in known locations, so the values defined there are not scattered throughout the code base or build system. Improved Performance and Minimal Size The Configurator enables the CLDC HotSpot Implementation ROMizer to compact and quicken the Java platform byte codes for Java Wireless Client software. The ROMizer runs static initializers at runtime, then compacts the final ROM image. However, the ROMizer cannot compact or quicken any class with a static initializer that calls native methods, nor can it compact or quicken any of that classs subclasses. The Configurator makes these calls unnecessary by ensuring that the Java platform and native values for properties and constants are the same.

The Configurator is critical to the optimization of Java Wireless Client software. It works with the CLDC HotSpot Implementation ROMizer, which compacts and quickens the Java platform byte codes for Java Wireless Client software. The ROMizer enables classes for the Java platform classes (Java classes) to be linked directly in the virtual machine. For information on the ROMizer utility, see the CLDC HotSpot Implementation Porting Guide. As shown in FIGURE 4-1, the Configurator reads data from input files, processes that data, then writes files to be used at later stages of compilation or release. It generates Java classes and associated native methods to support retrieving property and constant values.

Note If the system is built with the STATIC_PROPERTIES=true option, if you


add a property or constant, or update an existing value, you must rebuild the system before accessing new data in the Java Wireless Client source files. Otherwise, the properties are in text files that can be edited without having to rebuild SJWC.

24

Architecture and Design Guide December 2008

FIGURE 4-1

Configurator Work Flow for Constants and Properties Property output files:

Input for properties

properties_static_data.c internal.config system.config Configurator merges the input into a single XML file, then generates output files Constant output files:

Input for constants

Input for AUI skin properties (if AUI is used)

Various .java files as described in the input files. For example, Constants.java and LocalizedStringsBase.java For localized strings, .h and .c files are generated for each locale

Input for localized strings

Note If the Java Wireless Client is built using the option


USE_JAVACALL_PROPERTIES=true, the property output file jwc_properties.ini is generated instead of internal.config and system.config, as shown in FIGURE 4-1.

Input Files
The Configurator finds input files in one of two ways. First, you can add input file names to the INT_XML_FILES build variable. The second method is to list the input file names in midp/src/configuration/configuration_xml/platform/files.lst, which is read at build time. You can examine an existing copy of files.lst to understand how constants are defined. For example, midp/src/configuration/configuration_xml/javacall/files.lst references constants.xml, properties.xml, and rawimage.xml.

Chapter 4

Managing Properties and Constants

25

As shown in FIGURE 4-1, input can be provided for properties, constants, AUI technology skin properties (if AUI technology is used), and localized strings. The various types of input can be combined into a single file or multiple files, and can be mixed and matched as you wish. Input files can also be based on platform type or any other criteria you wish to create. For example, REPEAT_TIMEOUT and REPEAT_PERIOD are applicable only to the linux_fb version of Java Wireless Client software because repeated key events on other platforms are supported by the underlying native system. These input files must be organized in subdirectories of the directory configuration_xml. For example: midp/src/ configuration/ configuration_xml/ armsd/ linux_fb/ linux_qte/ stubs/ win32 share chameleon/ l10n/ The share/ directory contains Configurator input common to all of the platforms. The share/ directory and any of the other platform directories can contain alternative versions of the constants in constants_open and constants_fixed. They are selected based on the build resource policy defined by the USE_FIXED build option. In addition, the TARGET_DEVICE build option can be used to select alternate versions of input files within a specific platform. For example, the linux_qte directory contains constants, constants_omap730, and constants_x86. Setting the TARGET_DEVICE build option to omap730 or x86 during the build will cause the corresponding file to be used. It is also possible to define platform-dependent properties inside the JavaCall component. For an example, see the build option CONFIGURATION_PROPERTIES_FILE=properties.xml in javacall-com/configuration/sjwc/win32_emul/environment.gmk. (The properties.xml file is also located in this directory.)

26

Architecture and Design Guide December 2008

Note Input items must be unique in the merged XML file. If you provide different item values based on build flags, you must define these items in alternative input XML files.
The Configurator tool expects its input files to be in XML format. The following characteristics of Java Wireless Client software and its data make XML a good solution:

The structure of the data is simple, so the DTD can be in the file with the data itself, or in a separate file that the subsystems can share. The structures are flat, so a simple SAX parser with rudimentary error checking can be used instead of a full XML schema or DOM parser. XML is flexible enough that any style and format differences can be unified with XSL transformations, yet each subsystem can extend the DTD according to its needs. Because Java Wireless Client software requires JDK software version 1.4.1_01 or later, which includes a SAX parser, you do not need to install extra software on build machines.

For constants, the Configurator uses the input to generate the Java programming language and native source code to access the constants. It generates one class for each unique package-class pair in the input XML file. It also generates corresponding native header files that define the constants in #define statements. These are the files named Constants.java and midp_constants_data.h in FIGURE 4-1. For properties, the Configurator uses the input to generate one of the following types of files:

Source code The file properties_static_data.c is shown in FIGURE 4-1. Property files These are the files named system.config (for properties with a scope of system) and internal.config (for properties with a scope of internal) in FIGURE 4-1, or a single file, jwc_properties.ini.

With the property files, the Configurator also provides a default implementation of the Configuration class and correspondingly, the native files that read the properties from the .config files. Using the Configurator to generate the property files is a fall-back mechanism for maximum flexibility during porting. Due to the speed and size impact of processing property files at runtime, however, do not make this part of a deployed solution.

Chapter 4

Managing Properties and Constants

27

Properties
The Configurator requires the following information for properties:

Property name Value A setting that specifies whether the property is internal (only available to the Java Wireless Client software implementation) or system (also available to MIDlets) A system callout to retrieve a default value A comment (optional)

The Configurator uses a DTD shown to describe the input data for properties because the required information is diverse.

Modifying Properties
To change the value of an existing property, update the propertys XML element (the elements value attribute) in your properties input file.

Adding Properties
The following steps describe how to add a new property. 1. Determine the attributes of the property. The attributes are the propertys name, value, and scope. Optionally, you might also have as attributes a callout function name and a comment. If you define a callout function, you must also write a corresponding native function that has a name identical to the callout function name and a return type of char*. For more information on the attributes, see the DTD. 2. Add a new element your properties input file. For example:
CODE EXAMPLE 4-1

Adding a New Element to a Property File

<property Key="com.company.getDynamicValue" Value="" Scope="internal" Callout="getDynamicValue"/>

28

Architecture and Design Guide December 2008

Constants
The Configurator requires the following information for constants:

The name of the package and class that contain the constant The scope of the class that contains the constant The comment associated with the class (optional) The name of the constant The data type The value The scope of the constant itself, as opposed to the class that holds it The comment associated with the constant itself, as opposed to the comment associated with the class that holds it (optional)

In addition, you can specify JavaOnly or NativeOnly attributes to restrict the generation of a constant. The Configurator tool uses a DTD to describe the input data for global variables.

Modifying Constants
Most constants define platform-specific values, such as the screen size of the device, the number of supported colors, and so on. Internal constants are also used. They are clearly marked with internal in the comment attribute. You must update the platform-specific values to match your device, but can safely ignore the values of internal constants. Follow this step to change the value of an existing constant:

Update the constants XML element (the elements Value attribute) in your constants input file.

Adding Constants
Use the Configurator to maintain consistency between the Java platform and native layers. If you need a new constant in only the native layer or Java layer (but not both), do not to add it to the Configurator. Define the constant in your code. If you use the Configurator for every constant, even those used in only one layer, you needlessly increase Java Wireless Client softwares footprint.

Chapter 4

Managing Properties and Constants

29

The following steps describe how to add a new constant. 1. Determine the attributes of the class from which the constant is accessed in the Java platform. The attributes are the classs package, name, and scope. Optionally, the class can also have a comment associated with it. All Java Wireless Client software constants are accessed in the Java layer from the com.sun.midp.configurator packages Constants class. For more information on the attribute values, see the DTD. 2. Determine the attributes of the constant. The attributes are the constants name, value, and scope. Optionally, the constant can also have a type (the default is int) and a comment. For more information on the attributes, see the DTD. 3. Add a constant_class element to your constants input file if an element with the same package and class is not already in the file. For example:
CODE EXAMPLE 4-2

constant_class Element in Constants Input File

<constant_class Package="com.company.midp.Configurator" Name="Constants" Scope="public"> </constant_class>

4. Add a new constant element to the appropriate constant_class element of your constants input file. For example:
CODE EXAMPLE 4-3

constant Element in constant_class Element of Input File

<constant_class Package="com.company.midp.Configurator" Name="Constants" Scope="public"> <constant Name="MyPlatformNewConstant" Value="123" Vscope="public" Comment="This is a comment to keep track of my MyPlatformNewConstant constant"/> </constant_class>

30

Architecture and Design Guide December 2008

Changing the Output Format of Constants


If you must change the way constants are specified, modify the eXtensible Stylesheet Language (XSL) files contantsJava.xsl and constantsNative.xsl located in the midp/src/tool/configurator/xsl directory. The Configurator uses the XSL files to create the code for constants. Do not edit the XSL files if you want to use the default settings to generate the source code.

Chapter 4

Managing Properties and Constants

31

32

Architecture and Design Guide December 2008

Using the Logging, Tracing, and Assertion Services


The Logging, Tracing, and Assertion services are three independent services that make use of one subsystem to assist in the debugging process. These services provide a way to collect information about Java Wireless Client software. The following is a brief description of each service:

logging Service - Collects generic information, from assertion validations to system metrics. Writes output to a file. Tracing Service - Collects information about unexpected errors for which the programmer wants the error record to explicitly include the associated Throwable or the location (if available) of stack trace information. Writes output to a console. Assertion Service - Used to double-check statements and conditions that must be true. Depends upon the Logging Service.

Unlike desktop systems, small devices usually do not support calls like printf or System.err.println. The Logging, Tracing, and Assertion services provide a way to capture information about how the software is performing during the porting and debugging process. Java Wireless Client software contains two implementations, one that logs to the PCSL print subsystem and another that disables logging and tracing. For example, a working PCSL print subsystem provides you with the means to get output from the device by funneling all print activity through the devices serial line, to a memory buffer, or a to file on the device.

Note Be sure to turn logging, tracing, and assertion functionality off in the
production versions of your platform.

Chapter 5

Using the Logging, Tracing, and Assertion Services

33

The Logging, Tracing, and Assertion services can report runtime information from within both the native layer and the Java platform layer. It enables you to differentiate between various types of information and their levels of importance. It provides compilation options so that you can control the type and importance of information to log, including the production of binaries with no instrumentation calls. The API component provides both Java platform and native APIs. The APIs are similar because the Java platform API maps to the native API. The native API is the public interface to the implementation component. The API component does not need to be ported because it does not change across platforms. You can extend the Logging, Tracing, and Assertion services by adding additional channels (see Adding Logging Channels on page 37). Channels are identifiers for trace statements in the source code. A channel might identify information coming from a particular subsystem.

Building to Enable the Logging, Tracing, and Assertion Services


The Logging Service has three implementations:

JavaCall Static Dynamic

To enable the Logging Service, you must set the appropriate variable at build time. For example, if you build Java Wireless Client software for a JavaCall platform (the default system build configuration), the JavaCall version of the Logging Service is included. To enable the JavaCall version of the Logging Service, you must set USE_JAVAUTIL_LOG_IMPLEMENTATION=true. On a non-JavaCall platform (or if you build a JavaCall platform and set USE_JAVAUTIL_LOG_IMPLEMENTATION=false), you have two options for setting up the Logging Service, a static implementation and a dynamic one. Static or dynamic logging is set using the USE_CONTROL_ARGS_FROM_JAD variable during build time. If USE_CONTROL_ARGS_FROM_JAD=false, a static logging implementation is built. A static logging implementation does not provide as much flexibility as a dynamic implementation.

34

Architecture and Design Guide December 2008

If USE_CONTROL_ARGS_FROM_JAD=true, you provide the ability to specify logging, tracing, and assertion settings for certain MIDlets during installation of that MIDlet. (This is true regardless of the MIDlets global settings.) You also provide the ability to change the MIDlets log settings during runtime.

Note The increase of flexibility provided by dynamic logging also increases the
footprint of the Java Wireless Client software. For more information see, Using the Logging, Tracing, and Assertion APIs on page 36.

Dynamic Logging and a MIDlets JAD File


If USE_CONTROL_ARGS_FROM_JAD=true is set during the Java Wireless Client build process, then the dynamic logging capability allows you to use the Logging, Tracing, and Assertion services during a MIDlets installation, or during execution of the MIDlet during runtime. However, some modifications of a MIDlets JAD file properties are needed to make use of this capability. To enable dynamic logging for a specific MIDlet, and control the MIDlets settings during runtime, you must modify the MIDP_CONTROL_ARG property in the MIDlets JAD file, using the syntax shown in CODE EXAMPLE 5-1.
CODE EXAMPLE 5-1

MID_CONTROL_ARG Syntax

JAD_CONTROL_PARAM = MIDP_CONTROL_ARGS EQUAL *( ; param) param = report_level / log_channel_param / permissions_param / trace_param / assert_param report_level_param = report_level EQUAL 1*DIGIT log_channels_param = log channels EQUAL 1*DIGIT *( , 1*DIGIT) permissions_param = allow_all_permissions trace_param = enable_trace EQUAL bool_val assert_param = enable_assert EQUAL bool_val bool_val = 0/1

As defined in the above JAD file syntax, the setReportLevel() method allows you to change the current report level during runtime. The enableTrace() and enableAsserts() methods make it possible to enable or disable these services during runtime as well.

Chapter 5

Using the Logging, Tracing, and Assertion Services

35

Using the Logging, Tracing, and Assertion APIs


The Logging and Tracing services, while similar, differ in the types of information they are designed to store. The Logging Service collects generic information, ranging from assertion validations to system metrics. The Tracing service collects information about unexpected errors for which the programmer wants the error record to explicitly include the associated Throwable or the location or (if available) of stack trace information. Whether you collect logging or tracing information, the Logging and Tracing services affect the footprint and performance of your Java Wireless Client software port. The size of the effect depends on the number of calls to the service. Always use these services in a way that enables you to compile it out of the system when your port is stable. When compiled out, it no longer contributes footprint or performance overhead.

Logging
You can control the logging level at compile time using the REPORT_LEVEL constant. In the Java platform, REPORT_LEVEL is a static final int field with a default value of ERROR. In native code, REPORT_LEVEL is defined using a preprocessor integer variable. To use the Java platform logging service in a way that it can be compiled out, use an if statement to test the log messages severity against REPORT_LEVEL. This is shown in CODE EXAMPLE 5-2.
CODE EXAMPLE 5-2

Testing a Log Messages Severity Against REPORT_LEVEL

... // normal codepath statements if (assertion_failed) { if (Logging.REPORT_LEVEL <= Logging.ERROR) { Logging.report(Logging.ERROR, ..., logMessage); } }

If the value of REPORT_LEVEL is set to a level higher than the log messages severity (for example, if REPORT_LEVEL is CRITICAL and the messages severity is WARNING) the compiler removes the code construct and no associated bytecodes are included in the resulting binary.

36

Architecture and Design Guide December 2008

To use the logging service in native code in a way that it can be compiled out, use the #if directive to test the log messages severity against REPORT_LEVEL. This is shown in CODE EXAMPLE 5-3.
CODE EXAMPLE 5-3

Using the if Statement Tests a Messages Severity

#if REPORT_LEVEL <= severity reportToLog(severity, ..., meaningfulMessage); #endif

The existing Java Wireless Client software code uses the Logging Service in this manner in both the Java platform layer and native layer.

Adding Logging Channels


If you add a new subsystem (for example, an OEM extension), you might want to add a channel definition to differentiate its logging. Do not remove any existing channels. To add a channel identifier, add an entry to the configuration file for constants. See Chapter 4 for more information. Once defined, you can use the new channel identifier when you call the logging API from the Java platform layer and native code.
CODE EXAMPLE 5-4 adds a channel definition for a Bluetooth module to the constants

configuration file. The constant_class element is already in the file and it is included in the example to show you where to place your new channel definition.
CODE EXAMPLE 5-4

Adding a Channel Definition for a Bluetooth Module

... <constant_class Package="com.sun.midp.services" Name="LogChannels" ...> ... <constant Type="int" Name="LC_BLUETOOTH" Value="12000" VScope="public" Comment="My new Bluetooth module channel"/> </constant_class> ...

Chapter 5

Using the Logging, Tracing, and Assertion Services

37

Tracing
You can control whether the Tracing Service is enabled using the TRACE_ENABLED constant (static final boolean). To use the trace() method in Java programming language code so that it can be compiled out, use an if statement to test whether TRACE_ENABLED is true. This is shown in CODE EXAMPLE 5-5.
CODE EXAMPLE 5-5

Using an if Statement to Test if TRACE_ENABLED is true

try { ... // normal codepath statements } catch (OutOfMemoryError oom) { if (Logging.TRACE_ENABLED) { Logging.trace(oom, traceMessage); } }

If TRACE_ENABLED is false, the compiler removes the code construct and no associated bytecodes are included in the resulting binary. The existing Java Wireless Client software code uses TRACE_ENABLED in this way. Java Wireless Client software does not have a public native trace API because the CLDC HotSpot Implementation virtual machine does not provide the native means to get stack trace information. Because of this, the trace method is only available at the Java platform level.

Assertions
You can control whether the Assertion Service is enabled using the ASSERT_ENABLED constant (static final boolean). The assertTrue() method reports a message to the Logging Service in the event the specified condition is false. The message string should include enough description that someone reading the message has enough context to find the failed assertion. To use the assertTrue() method in Java programming language code so that it can be compiled out, use an if statement to test whether ASSERT_ENABLED is true. This is shown in CODE EXAMPLE 5-6.

38

Architecture and Design Guide December 2008

CODE EXAMPLE 5-6

if Statement for ASSERT_ENABLED

if (Logging.ASSERT.ENABLED){ Logging.assertTrue(condition, meaningfulMessage); }

If ASSERT_ENABLED is false, the compiler removes the code construct and no associated bytecodes are included in the resulting binary.

Note Java Wireless Client software does not have a public native assert API.

Chapter 5

Using the Logging, Tracing, and Assertion Services

39

40

Architecture and Design Guide December 2008

Porting the Record Management System


This chapter discusses the design of and strategies for porting the record management service (RMS) subsystem. The RMS subsystem provides the record storage functionality required by the MIDP 2.0 Specification. The MIDP 2.0 Specification enables MIDlets to create and destroy record stores, each containing zero or more records. The space available to a MIDlet suite is device specific. By default, a MIDlet is given full access to any record stores created by MIDlets in its own MIDlet suite. A MIDlet can allow MIDlets from outside its suite access to record stores it creates, providing them full or read-only access. The RMS subsystem provides the functionality required to give MIDlets recordoriented persistent storage. It enforces an access permission policy, and optionally might enforce record store size constraints. The RMS subsystem also provides MIDlets the ability to filter records, and to access to records in sorted order. The following activities are outside the scope of the RMS subsystem:

Storage of MIDlet suites (JAR files, JAD files, and associated metadata). See Chapter 14 for information on this task. Storage of any metadata required by the MIDP runtime environment. Support for a low-level file system, directories, and other OS functionality.

The record management service subsystem is closely tied in with the following subsystems and services:

AMS, particularly the Scheduler Runtime security Storage service (unless a device-specific database is used)

Chapter 6

Porting the Record Management System

41

Design
The record management service subsystem has the following design requirements:

Portability The design has multiple porting layers to support more types of devices. For example, if a target device has a native database, it can plug into one layer, while a target device with a file system uses the storage service. Ports can take advantage of any storage a device provides. Performance This code must perform well for record stores of any size. Enforcement of system limits Some devices have limited storage space, have limited file name support, or both. Java Wireless Client software must handle these limitations.

Design Overview
FIGURE 6-1 shows a high-level overview of the RMS subsystem, which implements a record-based storage on top of a file system.
FIGURE 6-1

RMS Subsystem Components External APIs (incorporating a sandbox for managing record access) Java platform database implementation Java platform file system access Storage service

The shaded boxes indicate two potential porting levels for the RMS subsystem:

A platform with built-in record-management or database functionality can port RMS at the Java platform database implementation, ignoring the shaded boxes. A platform that has a file system, but not a built-in record-management system or database, uses the file system. See Chapter 8 for information on porting the service.

Given that few devices have native record-management or database functionality, most platforms use the storage service. See Porting on page 45 for more information.

42

Architecture and Design Guide December 2008

The following sections describe the function and design of the components in FIGURE 6-1.

External API and the Sandbox


The External RMS API and Sandbox component make the RMS APIs available to MIDlets, while ensuring that they follow the security policies defined in the MIDP 2.0 Specification. The policies specify that a MIDlet is never able to access data not created by a MIDlet, nor external record stores that do not allow such access. To enforce MIDP 2.0 security requirements, implementations must know the currently active MIDlet suite. The sandbox obtains this information from the AMS.

Detailed Design
The External RMS API component is a thin layer that passes calls through to

implementation classes under it. Both the External RMS API and the sandbox are implemented in the javax.microedition.rms.RecordStore class. The sandbox obtains the unique system ID of the currently running MIDlet suite from the scheduler. The scheduler is part of the Application Management Service (AMS) subsystem. See Chapter 14 for information. When a MIDlet opens the record store of another suite, the sandbox checks whether the record store allows access. See the MIDP 2.0 Specification for the permission semantics.

Design Rationale, Notes, and Considerations


Placing the sandbox in the RMS API component removes any dependencies of the database implementation on the AMS. The absence of a dependency simplifies replacing the Java platform database component.

Database Implementation
The database (the record store) component manages the storage of record stores and records. It has the following requirements:

Database management capabilities:


Create, delete, and open a database by unique suite and name identifier List databases by suite (Used by AMS and RMS) Delete databases by suite (Used by AMS)

Chapter 6

Porting the Record Management System

43

Size of database by suite and in aggregate (Used by AMS) Record store meta-information: size, version, last modified, next record identifier, number of records, and owner Record manipulation: add, delete, set, get, and size

Database functionality:

Java Wireless Client software implements the database component on top of a file system by mapping a record store to two related files, an index file, and a data storage file. The helper classes and native code manage the data files memory usage (amount of free space) and use the index file for record access (lookup, create, and delete).

Detailed Design
A record store is mapped to two files: a database (.db) data file and an index (.idx) file. The database file is an array of metadata, variable-length records, and free space from deleted records. The database implementation component manages free space. It uses the best-fitting, existing free space for new records, and compacts the file when there is enough free space for a new record but the space is not contiguous. The index file contains the offsets of records in the data file. It indexes the record by record identifier. The index is in a B-tree for fast access.

Design Rationale, Notes, and Considerations


Java Wireless Client software uses a different design from the MIDP 2.0 RI, to improve runtime performance and portability. The differences are in the following tasks:

Looking up offsets of records and free blocks Java Wireless Client software uses a B-tree, which has a worst-case search time of O(log(n)). This allows quick lookup times for locations of records and best-fit free blocks. The MIDP 2.0 RI stored record offsets and free block offsets in a linked list, has a worst-case search time of O(n).

Compacting the database file Java Wireless Client software compacts the database file when there is enough free space for a new record, but that space is not contiguous. Compacting as space is needed keeps file space utilization high, and does not slow calls to close the record store. The MIDP 2.0 RI compacted the database file when the record store is closed. This means that often, closing the record store is slow.

44

Architecture and Design Guide December 2008

Space-available checking By default, Java Wireless Client software does not perform this check. The MIDP 2.0 RI performs a check for free space at the start of most calls that modifies or inserts records, or created record stores. The free-space check is time consuming.

When porting the RMS subsystem, if the target device has a native database, the record store can be replaced with a layer mapping to the native database functionality. Mapping the native database at this layer allows the reuse of the public API layer and the sandbox. See Porting on page 45 for more information.

File System Access


The Java platform file system access component provides the file system capabilities required by the RMS database component. Most of the methods in the Java platform file system access component are native. The component defines file operations such as open, close, delete, truncate, read, and write. It also names record stores, confining the namespace of a record store to the scope of the creating applications MIDlet suite. This component exists for backward compatibility with older ports, as it is the code boundry between the native and Java layers in the MIDP 1.0 release. You can implement the database implementation component directly instead.

Porting
Which porting interface to use depends on the storage functionality available on the target. Keep the following guidelines in mind:

If the target has a POSIX-like API for the persistent storage subsystem (file system), start by porting the storage service. (See Chapter 8 for information.) If the target has a native database, start by porting the database implementation component. If the target has neither a native database implementation nor a POSIX-like API, consider porting the storage service. Implementing that functionality has the following advantages:

It is easier than implementing a native database. It facilitates porting the AMS subsystem, which also uses the storage subsystem.

Chapter 6

Porting the Record Management System

45

Follow these steps to port the database implementation component: 1. Compare the database implementation methods to your devices database API. The implementation is in the directory midp/src/rms/rms_base/classes/com/sun/midp/rms. Your API probably has more functionality than the RMS requires. 2. Determine whether you want to map each record store to separate native databases or use one native database for all the record stores. You can choose the latter only if you can provide a unique root for each record store. Otherwise, neither choice has an advantage. 3. Port two functions from midp/src/rms/record_store/file_based/native/rms.c if you use a native RMS. The two C functions are rmsdb_remove_record_stores_for_suite and rmsdb_suite_has_rms_data. 4. Remove the layers below the database implementation (except rms.c if you ported the functions in Step 3). When you port the database implementation component, your RMS does not need the layers below it. The layers of the RMS are shown in FIGURE 6-1.

46

Architecture and Design Guide December 2008

File Organization and Naming


This chapter describes how the Java Wireless Client software source code is organized and describes the naming conventions used for native files.

Source Code Organization


The following list shows the organization of the rest of the Java Wireless Client software source hierarchy. The files are located under the installDir/midp directory. src/ Top-level source directory subsystemX/ Top-level subsystem directory subsystem.gmk The subsystem makefile that combines the library makefiles for this subystem and defines settings common to the subsystem libraryY/ Top-level library directory libraryY/lib.gmk Library makefile. Contains rules and settings specific to this library. libraryY/include The libraryY exported native interface libraryY/classes/ Exported Java programming language interface implementationZ/ Implementation of this library implementationZ/lib.gmk Implementation makefile. Contains rules and settings specific to this implementation. implementationZ/libinfo.gmk Implementation descriptor. Specifies dependencies on other libraries. implementationZ/include Additional native exported interfaces specific to this implementation

Chapter 7

File Organization and Naming

47

implementationZ/classes Java programming language class files for this implementation implementationZ/native Native files for this implementation SubsystemX represents a Java Wireless Client software subsystem or service such as the record management system or the high-level user interface. LibraryY represents one of the libraries that constitute subsystemX. ImplementationZ is one of the alternative implementations of libraryY. TABLE 7-1 shows the Java Wireless Client software subsystems and their libraries. For libraries with more than one implementation, the alternative implementations are listed.
TABLE 7-1 Subsystem

Java Wireless Client Software Subsystems and Libraries


Libraries Description

ams/

ams_api

Public API defined by the MIDP specification for the following: javax.microedition.midlet. MIDlet javax.microedition.midlet. MIDletState ChangeException AMS functionality: Initializes MIDP Runs a MIDlet Registers, unregisters and gets the AMS isolate ID Gets the current foreground isolate ID and display Stub interfaces that handle functionality provided by optional packages Miscellaneous AMS utilities: Start and terminate a MIDlet Verify a MIDlet suite Change an isolates priority Functionality required to generate a binary image from the MIDlet suite classes Functionality to create an application image file

ams_base

ams_jsr_interface

ams_util

app_image_gen

app_image_gen_base

48

Architecture and Design Guide December 2008

TABLE 7-1 Subsystem

Java Wireless Client Software Subsystems and Libraries (Continued)


Libraries Description

appmanager_ui

Application manager UI-related functions: Displays a splash screen Displays a screen to enable MIDlet selection Changes a MIDlet suites settings Shows a MIDlet suites information Export resources (splash screen picture) required by the application manager UI Testing functionality provided by AutoTesterInterface Functionality required by the autotester library that is common for all implementations

appmanager_ui_resources

autotester autotester_base

cdc_application example installer jams The classes and functions that install a MIDlet suite The Java programming language implementation of the AMS (Java AMS)

jump_application midlet_suite_info mvm nams nams_javacall ota platform_request Discovery application and graphical installer MIDlets Native platformRequest() function used to start a new process to handle a given URI Functions that deal with MIDlet suite storage Simple attribute storage for MIDlet suites An MVM-specific API that starts a MIDlet suite in a new isolate The API for a native AMS (NAMS)

suitestore verifier

Chapter 7

File Organization and Naming

49

TABLE 7-1 Subsystem

Java Wireless Client Software Subsystems and Libraries (Continued)


Libraries Description

automation/ configuration/ configuration_xml properties properties_port core/ crc32 global_status javautil kni_util libc_ext log log_base memory native_thread resource_handler resource_manager services storage string suspend_resume timer_queue timezone vm_services

The internal automation API implementation Configuration XML data Functions that provide access to MIDP properties from the Java platform Functions that provide access to MIDP properties from the native platform Functions that provide the CRC32 checksum calculation Global status constants definitions Basic Java platform utility classes (for example, DateParser) Common helper functions on top of KNI ANSI C extensions (for example, snprintf) Native and Java platform logging support

Native heap memory facility Native threading facility Functions that provide access to system resources Native platform resource accounting

Native storage abstraction layer String operations

Native timer queue for master mode Timezone information Miscellaneous services provided by the VM (current time, current isolate ID, thread wait and signal)

demos/

50

Architecture and Design Guide December 2008

TABLE 7-1 Subsystem

Java Wireless Client Software Subsystems and Libraries (Continued)


Libraries Description

events/

eventqueue eventqueue_port eventsystem

Java platform and native platform events and event queues Platform-specific event queue implementation Event processing-specific functionary (master mode vs. slave mode), the main VM loop, event checking

input_port mastermode_port slavemode_port highlevelui/ annunciator armsd_application directfb_application fb_application fb_port javacall_application keymap lcdlf lcdui lfjport lfpport nativepti_port nim_port pti_api Java platform interface to predictive text support (javapti and nativepti implementations) Linux Qt-specific services Mapping between key codes, game actions, key names UI look and feel Java platform high-level UI (display and displayables) Java platform look and feel porting interface Platform look and feel porting interface Platform-specific implementation for native predictive text support Linux/FB-specific services Platform-specific master mode implementations Platform-specific slave mode implementations Annunciators (sound, vibration, network indicators) ARMSD-specific services

qte_application

Chapter 7

File Organization and Naming

51

TABLE 7-1 Subsystem

Java Wireless Client Software Subsystems and Libraries (Continued)


Libraries Description

win32_application wince_application i18n/ i18n_main

Win32-specific services

Functions that provide character conversion and access to locale-specific information Interface to platform-specific character converters

i18n_port links/ classes i3test native lowlevelui/ graphics graphics_api graphics_util platform_graphics_port media/ mmapi/ nuts/ reference classes include reference porting_demos/ protocol/ cdc_application file gcf http https serial serial_port socket socket_notify ssl ssocket

PutPixel and platform graphics implementations Java platform low-level UI (drawing primitives, fonts, images) Common services for PutPixel and platform graphics Porting interface for platform graphics

Internal file access Base networking classes HTTP connections HTTPS connections Serial port connections Serial port connection porting interface Socket connections Network event notification facility SSL connections Server socket connections

52

Architecture and Design Guide December 2008

TABLE 7-1 Subsystem

Java Wireless Client Software Subsystems and Libraries (Continued)


Libraries Description

udp push/ nativepush_port push_api push_gcf push_server

Datagram connections A native (external) push implementation The Java platform push API and implementation

A low-level push implementation. An interface to subsystems providing resources on which push can be registered. A platform-specific alarm-based push implementation

push_timer restricted_cry pto/ rms/ reference record_index record_store rms_api rms_base rms_exc security/ crypto file_digest internal_api_protection midp_permissions native_dialog_port permission_dialog

RMS index (linear, tree) Native interface to RMS Java platform interface to RMS Basic RMS utilities Java platform RMS exceptions Interfaces to crypto functions and the exportable implementation classes Classes used to create an unpredictable digest of a file Classes used to protect public internal APIs from unauthorized use Policy used for grouping MIDP permissions Switch library used for native permission dialogs Classes used to enable the user to grant or deny a running MIDlet suite a MIDP permission The PKI certificate API Trusted public key storage

pki publickeystore

Chapter 7

File Organization and Naming

53

TABLE 7-1 Subsystem

Java Wireless Client Software Subsystems and Libraries (Continued)


Libraries Description

secure_random

Functions that provide unpredictable random data. Each implementation is device specific.

ssl/ test/ tool/

reference common chameleon fontgen imageutil jadtool l10ngen mekeytool upgradel10n

See the Build Guide for instructions about how to add a directory for your platform, as well as subsystems and libraries. When you add a new library to the existing subsystem, put the exported native interface of this library into a subdirectory named include. Then add one or more implementations of this interface into the respective subdirectories.

Naming Convention for Native Files


Subsystems and libraries use the following naming conventions.

Files whose names end with the _md suffix contain implementations of functions that use system-specific mechanisms that are likely to differ from device to device. The _md suffix stands for machine dependent. The functions in these files are not public.

54

Architecture and Design Guide December 2008

Native files in libraries that belong to the low-level UI and high-level UI subsystems are named with the library-specific prefixes shown in TABLE 7-2.
Native File Library Prefix Examples
Prefix

TABLE 7-2 Library

graphics_api graphics

graphics_util platform_graphics_port annunciator armsd_application directfb_application fb_application javacall_application keymap lcdlf (lfjava, lfplatform implementations) lfjport lfpport qte_application wince_application win32_application

gxapi_ gx_ (shared include files) gxj_ (putpixel) gxp_ (platform_graphics) gxutl_ gxpport_ anc_ armsdapp_ directfbapp_ (unsupported) fbapp_ jcapp_ keymap_ lcdlf_ (lfj_, lfp_) lfjport_ lfpport_ qteapp_ winceapp_ (unsupported) win32app_

Chapter 7

File Organization and Naming

55

56

Architecture and Design Guide December 2008

PCSL
This chapter discusses how to use the Portable Common Services Library (PCSL) in the porting process. PCSL is the Portable Common Services Library. It is portable in the sense that it defines a set of interfaces that higher-level implementations use. It is common in that both MIDP and CLDC implementations use the interfaces defined by PCSL. PCSL is a family of different libraries:

Networking File system Memory allocation Printing String

These libraries are largely independent of each other and can be ported separately. However, some of the implementations do depend on other parts of PCSL. For example, the PCSL file system implementations rely on the PCSL memory allocation interfaces. A notable feature of PCSL is that multiple implementations of each porting interface are available. Each implementation resides in a module. When building PCSL, you choose one implementation module for each library. For example, PCSL has two implementations of the networking interfaces: one that implements networking using BSD sockets, and another that sends network packets over a serial port. The SoS module is useful during development and porting if a true network is not available.

Note The SoS module is not suitable for use in production products.
On the other hand, the memory allocation library has two implementation modules: a malloc-based implementation and a heap-based implementation. Either module is suitable for use in production.
Chapter 8 PCSL 57

Each PCSL library also contains a module consisting only of a set of stubs. This is not an implementation. Rather, it is a skeleton that you can use to create an entirely new implementation module. This is useful if none of the implementation modules provided in PCSL is a good match to the underlying platform. When you build PCSL, be sure that the self tests are linked and then run the tests to verify that the build works. Note that the test results must be available though the output functionality described in Set Up and Configure Your Device Development Environment on page 11.

PCSL Print Library


The PCSL Print library is extremely simple and consists of a single function: pcsl_print(). This function takes a NULL-terminated string and prints it to an implementation-specific location. By itself, this function does not provide much value. However, because all debugging and error messages in the system are passed through this function, it is possible to redirect all of this output by modifying or reimplementing this one function. The PCSL Print library has two alternate implementations: one that prints to the standard output (stdout) and one that prints to a file (file). Both implementations always flush their output so that no data is left in any internal buffers. The stdout implementation sends output to the UNIX system standard output stream. If your platform is a UNIX operating system or a similar system (for example, Linux), use the stdout implementation. The process that invokes the Java Wireless Client software (such as a shell) can often conveniently redirect standard output without any change to the Java Wireless Client software itself. The file implementation opens a file and sends its output to it. In this implementation, the PCSL Print library uses the file operations defined in the PCSL File library. The file implementation of PCSL Print is useful if the UNIX system style standard output stream is not available, or if it is difficult to redirect.

58

Architecture and Design Guide December 2008

PCSL Memory Allocation Library


The memory allocation library provides interfaces to allocate, resize, and deallocate dynamic memory. It also has functions to duplicate strings and to get information about heap memory allocated and available. The PCSL memory allocation interface is defined in the pcsl_memory.h header file. Dynamic memory allocation is one of the most-used functions in any software system. Therefore, the PCSL memory allocation library is one of the first libraries that you port. The PCSL memory allocation library provides two different implementation modules. The first implementation, the malloc-based implementation, simply calls the standard C functions malloc(), calloc(), realloc(), and free(). If the underlying platform supports these functions, then the malloc-based library offers the quickest route forward. The other implementation module, the heap-based implementation, implements its own memory allocation within a contiguous block of memory. This implementation is suitable for production, and it is sometimes preferable to the malloc-based implementation. The heap-based implementation allocates from a single contiguous range of memory and so is suitable for situations where the Java platform is limited to a specific amount of memory, or if it is desirable for memory allocated by the Java platform to be kept separate from memory allocated by other parts of the system. In addition, the heap-based implementation provides diagnostic facilities to detect things like memory leaks and buffer overrun situations. Two modes are provided: debug and non-debug. In debug mode, C preprocessor macros are employed to provide the file name and line number from which the function was called. This information is stored inside the heap structures, so that a heap block can be examined to determine the location in the source code where it was allocated. This extra information is not present in non-debug mode. In most PCSL libraries, the boundary between interface and implementation is established by declaring functions in C header files and providing multiple implementations of those functions in different sets of C source files. The memory allocation library defines the boundary between interface and implementation differently: instead of being based on C functions, it is based on C preprocessor macros. Suppose you use the malloc-based implementation. The main PCSL memory allocation function is named pcsl_mem_malloc(). If this is a C function, the function simply turns around and calls malloc(). However, this incurs extra function call overhead for every memory operation. To avoid this overhead, the PCSL memory allocation library defines C preprocessor macros that compile out this extra layer. Thus, in the malloc-based implementation module, pcsl_mem_malloc() is a C preprocessor macro that is defined to expand to malloc().

Chapter 8

PCSL

59

Given that the porting layer for the PCSL memory library is implemented through C preprocessor macros, the conventions for implementing the memory allocation interfaces are unusual. The main header file pcsl_memory.h includes the following statements:
#include <pcsl_memory_impl.h> /* ... */ #define pcsl_mem_malloc(x)

To develop a new implementation of the PCSL memory interfaces, you must provide a header file named pcsl_memory_impl.h. In this file, you either define pcsl_mem_malloc_impl() as another preprocessor macro, or you can simply provide an ordinary extern C function declaration. Use similar techniques for the other pcsl_mem interfaces.

Porting malloc-Based Implementations


Consider the following reminders when porting the malloc-based implementation:

The function pcsl_mem_malloc() must allocate and return a valid heap block even if the size passed is zero. Some system malloc() calls might return NULL in this case. If this is true, a wrapper function must be added to handle this special case. Some memory allocation implementations do not require initialization and finalization functions. However, PCSL requires them. In this case, it is sufficient to define the initialization and finalization as macros that evaluate to zero. The expressions must evaluate to zero, otherwise an error occurs. If pcsl_mem_free() is passed a NULL pointer, it must handle it without error. The heap-based implementation module handles this internally. The mallocbased implementation includes a macro that checks for NULL before calling the underlying free() function. If the underlying platform provides malloc() and free() but not all of calloc(), realloc(), or strdup(), it is straightforward to implement any of the last three in terms of malloc(). The heap-based implementation has code that implements these functions in terms of pcsl_mem_malloc() and can be used as an example. The three functions pcsl_mem_get_total_heap(), pcsl_mem_get_free_heap(), and pcsl_mem_malloc_dump_memory() merely provide additional information about the state of the memory subsystem. However, because they are only used to provide information, it is adequate to define these APIs as no-ops, especially if the underlying system APIs do not provide a one-to-one mapping with these APIs.

60

Architecture and Design Guide December 2008

Chunky memory consists of memory blocks that can be shrunk or expanded after they are allocated. It is used by the Java platform heap to use memory efficiently based on the current load of the VM. When an existing chunk of memory is adjusted, its starting address must remain unchanged. The default implementation uses the Linux mmap function to implement these chunky memory functions. If the underlying platform does not have a similar mechanism, you can simulate chunky memory with regular malloc by preallocating the maximum block size and adjusting end pointer or size upon adjust calls. For an example, see Porting the Heap-Based Implementation on page 61.

Porting the Heap-Based Implementation


The heap-based implementation is generic, requiring only a contiguous block of memory from which it allocates. This block of memory is initialized in two ways:

If PCSL_MEMORY_USE_STATIC is defined, the memory manager uses the stack for its available memory pool. For example: static char PcslMemory[DEFAULT_POOL_SIZE]; If PCSL_MEMORY_USE_STATIC is not defined, it calls the C function malloc() and free() to allocate and free the memory pool. If malloc() and free() are not available, you must substitute the appropriate functions. Note that you cannot use pcsl_mem_malloc() or pcsl_mem_free() here because that creates a circular dependency.

The chunked memory operations are implemented by three functions:


pcsl_mem_allocate_chunk() pcsl_mem_adjust_chunk() pcsl_mem_free_chunk()

These functions have generic implementations based on pcsl_mem_malloc and pcsl_mem_free. They do not require any porting.

Chapter 8

PCSL

61

PCSL File System Interface


The PCSL file system interface provides the persistent storage functionality required to load classes, images, and to store JAR and JAD files. The PCSL file system hides directory hierarchies by making the file system look flat. This feature enables Java Wireless Client software to work with file systems that do not support hierarchical directories. Note that the ability to list files is required by the following interface functions:

pcsl_file_openfilelist pcsl_file_getnextentry pcsl_file_closefilelist

All file names are based on the 16-bit Unicode Standard. This feature allows maximum performance when the underlying platform supports the Unicode file system directly. The PCSL file system interface is defined in the pcsl_file.h and pcsl_directory.h header files. PCSL provides two file system implementation modules. The first implementation is based on POSIX file system APIs and is suitable for use in production. The second simulates a file system in RAM and is suitable for use during development and porting. The POSIX module supports a hierarchy of directories, while the RAMbased module supports a flat namespace. The first porting step is to determine what file system APIs are available on the underlying platform. If POSIX APIs are available, or if the APIs available are POSIXlike, start with the POSIX implementation module and modify it as necessary for the platform. If the file system API available is very different from the POSIX APIs, it is probably necessary to create an implementation from scratch using the stubs module. If the file system APIs are not available, or if some time is required to port to the available file system APIs, the porting effort can proceed by using the RAM-based file system implementation module. As noted previously, the RAM-based module is not suitable for production. In particular, because it is RAM-based, its files are not persistent. However, a file can be read later in the same test run and files can be preloaded into the RAM-based file system.

62

Architecture and Design Guide December 2008

A PCSL file system implementation is required to implement the following functions:


pcsl_file_init() pcsl_file_finalize() pcsl_file_open() pcsl_file_close() pcsl_file_read() pcsl_file_write() pcsl_file_unlink() pcsl_file_truncate() pcsl_file_seek() pcsl_file_sizeofopenfile() pcsl_file_sizeof() pcsl_file_exist() pcsl_file_commitwrite() pcsl_file_rename() pcsl_file_openfilelist() pcsl_file_closefilelist() pcsl_file_getfreespace() pcsl_file_getusedspace() pcsl_file_getnextentry() pcsl_file_getfileseparator() pcsl_file_getpathseparator() pcsl_file_is_directory() pcsl_file_mkdir() pcsl_file_rmdir() pcsl_file_getfreesize() pcsl_file_gettotalsize() pcsl_file_get_attribute() pcsl_file_set_attribute() pcsl_file_get_time()

See the pcsl_file.h and pcsl_directory.h header files for a complete specification of these functions.

Chapter 8

PCSL

63

PCSL Networking Library


The PCSL Networking Library provides portable interfaces for client-side sockets as well as for a variety of utility functions such as host name lookup. PCSL provides support for datagrams and server-side sockets. The APIs support asynchronous operation to avoid blocking the caller during a long-running network operation. To this end, most of the networking operations are split into two parts: a start function and a finish function. The start function initiates the operation, and the finish function collects the results. A notification step must also occur between the start function and the finish function. After an operation is started, the implementation must provide some means of notifying PCSL when the operation completes and is ready for the finish function to be called. In some cases, notification originates within PCSL itself. The start function and the finish function must each be called from a native method because when the start function initiates an operation, it might return the code PCSL_NET_WOULDBLOCK. This indicates that the calling Java programming language thread must be blocked, and that a notification context must be set up. When the operation completes, notification occurs, and the calling Java platform thread (Java thread) is awakened. When a Java thread is awakened after was blocked in a native method, the native method is restarted. This native method then calls the finish function. See the Coding Styles for Long-running Native Methods section in Chapter 6 of the CLDC HotSpot Implementation Porting Guide for further information about this technique. PCSL provides the following networking operations: open, read, write, close, and gethostbyname. Each function is prefixed with the string pcsl_socket_ for socket operations and with the string pcsl_net_ for general networking utilities. The suffixes _start and _finish are used to name the start functions and finish functions. For example, the finish function for the write operation is named pcsl_socket_write_finish(). Additionally, several other operations, including operations for getting and setting socket options are available. These operations update and retrieve state synchronously, so they have no start functions or finish functions.

64

Architecture and Design Guide December 2008

Note Operations are not required to be asynchronous. The start function is not
required to return PCSL_NET_WOULDBLOCK (which causes an eventual call to the finish function) if the operation can be completed immediately. For example, if pcsl_socket_read_start() is called and enough data is already available, this function can return that data directly instead of returning the code PCSL_NET_WOULDBLOCK. In this case, no notification occurs, and pcsl_socket_read_finish() is not called. A complete specification of the PCSL network APIs is provided in /network/pcsl_network.h.

Handles and Contexts


A couple of abstractions are added to the PCSL networking APIs to make them both portable and asynchronous. The APIs use a handle (a void * value) to represent an open socket. The pcsl_socket_open_start() function creates and returns a handle. The pcsl_socket_open_finish() function and the start- and finishfunctions that implement the other socket operations (read, write, close, and so on) all take a handle as a parameter. The handle becomes invalid after the close operation completes. A handle can be a pointer to a block of allocated memory or it can be a value like a UNIX system file descriptor (an int). If a handle is a pointer to allocated memory, the pcsl_socket_open_start() function must allocate it and one of the pcsl_socket_close_*() functions must deallocate it when the close operation completes. The asynchronous nature of the APIs requires you to set up information about pending operations during the start function and carry across to the finish function. This is handled through the context object (another (void *) value). Each start function is allowed to create and return a context object. After notification is received, the system finds the proper context object and passes it to the finish function. The context can be a pointer to a block of allocated memory. In this case, the start function allocates the block and the finish function deallocates it. If an implementation does not need a context (for example, the context might be maintained implicitly in the handle), the start function returns NULL for the context, and the finish function ignores the context parameter.

Chapter 8

PCSL

65

Alternative Networking Implementations


PCSL provides five alternative networking implementations. The winsock implementation provides a binding to Microsoft Windows networking. The javacall implementation provides a binding from PCSL to the JavaCall porting layer. If you have already implemented the JavaCall network APIs, then the PCSL javacall implementation can be used without modification. The javacall implementation relies on JavaCall API notifications and JavaCall API events mechanism to deliver networking and socket events from the platform to the upper layers of the MIDP implementation. For more information, please see the JavaCall API documentation. The five networking implementations are illustrated in the following diagram. The SoS implementation implements sockets over a serial line. The BSD implementation uses the BSD UNIX system socket API. The BSD implementation has two variants: a generic implementation that uses plain BSD sockets and a QTE-based implementation that wraps each socket inside a Qt object.

66

Architecture and Design Guide December 2008

FIGURE 8-1

Five PCSL Networking Implementations


QTE-Based BSD Implementation Generic BSD Implementation SoS Implementation

JavaCall Implementation

WinSock Implementation

MIDP

MIDP

MIDP

MIDP

MIDP

pcsl_network.h

pcsl_network.h

pcsl_network.h BSD Common BSD Common

pcsl_network.h BSD Common pcsl_network_na.h

pcsl_network.h SoS pcsl_network_serial.h

SoS JavaCall

WinSock

pcsl_network_na.h

BSD sockets QTE

BSD Generic

pcsl_serial_linux

JavaCall Platform

Win32 Platform

BSD sockets and QTE

BSD sockets Implementation

Linux

The following table shows where the technologies listed in FIGURE 8-1 are located in the Java Wireless Client software release.
TABLE 8-1

PCSL Technologies File System Locations


Directory Location

Implementation

JavaCall WinSock SoS

pcsl_dir/network/javacall pcsl_dir/network/winsock pcsl_dir/network/sos

Chapter 8

PCSL

67

TABLE 8-1

PCSL Technologies File System Locations (Continued)


Directory Location

Implementation

pcsl_serial_linux.c BSD Sockets and QTE BSD Generic

pcsl_dir/network/serial/ pcsl_dir/network/socket/bsd/qte pcsl_dir/network/socket/bsd/generic

BSD Implementations
The implementations of the PCSL networking interfaces use the BSD socket APIs, for example, socket(), bind(), and connect(). The BSD-based implementations are suitable for production use. The BSD implementation places all sockets into nonblocking mode so that the PCSL start functions do not block the caller. The BSD implementation has two variants: a generic one that uses socket descriptors directly, and one that uses QTE. The generic implementation relies on external code to call select() (or equivalent functionality) to determine when the socket operation is complete. The QTE implementation wraps each socket into a VMSocket object and sets up a QSocketNotifier object to handle notification of socket state changes. If your platform uses BSD sockets and has a callback-based notification scheme, start your port with the BSD QTE implementation. If your platform uses BSD sockets but uses a select()- or poll()-based notification scheme, start your port with the BSD generic implementation. PCSL provides an internal interface called the notification adapter that enables code to be shared between the BSD generic and BSD QTE implementations. This interface is defined in the header file /network/socket/bsd/pcsl_network_na.h. Both BSD implementations create and use BSD socket descriptors, but only the QTE implementation also creates VMSocket and QSocketNotifier objects. The notification adapter allows BSD common code to deal with sockets as abstract handles. In the BSD generic case, the handle is simply the socket descriptor, whereas in the BSD QTE case, the handle is a pointer to a VMSocket object. You might find the notification adapter interfaces useful if the platform supports BSD sockets but uses a notification scheme other than QTE.

68

Architecture and Design Guide December 2008

Socket-over-Serial Implementation
The SoS implementation simulates a network connection by sending packets over a serial line. This implementation is suitable for use during development and porting and is not typically put into production. Instead of opening a socket for each network connection, the SoS implementation multiplexes one or more network connections over a single serial port. This implementation uses a low-level serial port API internally. PCSL provides an implementation of this low-level serial API for Linux-based systems. Because the SoS implementation does not rely on any system libraries (except serial I/O), you have more control over the packets that are sent to the server and the way those packets are handled. This control gives you the option to send debug data (pcsl_print() output) using the SoS implementation as auxiliary packets that the server can decode and print in a console or debugging window. To bring up SoS networking on a device with a serial port, first evaluate its serial APIs. If they are similar to Linux or the UNIX system, you can start with the existing serial port code and bring up the SoS networking on top of that. If the devices serial APIs are different from the UNIX system, create an implementation of the low-level serial API that maps the API calls to platform-specific serial port calls. The low-level serial API is defined in /network/serial/pcsl_network_serial.h. A Java programming language program written for the Java SE platform is provided to act as an SoS proxy server. The SoS proxy server opens a socket connection with the other end and does all the networking operations on behalf of the actual device. Communication between the device and the proxy server is done using a method similar to RPC. The proxy server also allows SoS connections to be demultiplexed to the actual network connections. During development, it is useful to connect a device to a desktop workstation through a serial port, and then to connect the workstation to a local-area network.

Notification
To initiate a network operation, the start function is called from a native method, and the calling Java thread is blocked. At this point, it is crucial that the platform have some means of notifying PCSL when a networking operation is complete. The means for this notification is highly system specific. The alternative PCSL networking implementations handle notification differently. The BSD generic implementation uses plain BSD socket descriptors, which have no intrinsic notification capability. Instead, this implementation requires external code to call select() or poll() with this file descriptor. For example, if the CLDC HotSpot Implementation VM is running in normal mode (as opposed to slave
Chapter 8 PCSL 69

mode), code in the JVMSPI_CheckEvents() function checks the socket descriptor to determine when an operation completes and to awaken the Java thread that was blocked on the operation. The BSD QTE implementation uses the QSocketNotifier mechanism, which provides a callback into PCSL code when a socket operation completes. This necessitates a call from PCSL into the rest of the system. PCSL calls the function NotifySocketStatusChanged() when a sockets state changes. This function is not provided by PCSL, but is provided externally as part of the upper layers of the MIDP implementation. This function is responsible for finding and awakening the Java programming language thread that was blocked on the socket operation. Although it is not typical, initialization of the networking system on some platforms may be asynchronous. In this case, PCSL provides a callback function that is passed as a parameter of pcsl_network_init_start() and pcsl_network_finalize_start(). When the network initialization or finalization is completed, the following is the type of function that will be called: typedef void (*PCSL_NET_CALLBACK) (int init, int status); The SoS implementation does not use notification at all. Instead, it relies on the caller to poll or to sleep for a specific period of time until the operation is presumed to be complete. As such, the SoS implementation is unsuitable for production use. See Chapter 13 for further information on normal and slave modes.

PCSL String Library


The PCSL String Library provides portable interfaces for basic string operations. The API defines an opaque pcsl_string type and contains functions for the creation and manipulation of pcsl_string instances. The first porting step is to determine an internal representation of pcsl_string that is optimal for the platform. The reference implementation provides a pcsl_string definition based on UTF-16 encoding to match the internal representation of Java programming language string objects. On Microsoft Windows platforms, it is reasonable to use the UTF-16 representation because the Windows API functions support it. On platforms that do not support 16-bit characters, but do support UTF-8, it might be reasonable to select the UTF-8 internal representation to avoid repeated conversions of the same PCSL string to UTF-8. It is also possible to have an internal PCSL string representation that caches different encodings of the same string to achieve maximum performance.

70

Architecture and Design Guide December 2008

A PCSL string implementation is required to implement the following functions:


pcsl_string_is_active() pcsl_string_initialize() pcsl_string_finalize() pcsl_string_length() pcsl_string_utf16_length() pcsl_string_utf8_length() pcsl_string_convert_to_utf8() pcsl_string_convert_to_utf16() pcsl_string_convert_from_utf8() pcsl_string_convert_from_utf16() pcsl_string_equals() pcsl_string_compare() pcsl_string_cat() pcsl_string_dup() pcsl_string_append() pcsl_string_append_char() pcsl_string_append_buf() pcsl_string_predict_size() pcsl_string_substring() pcsl_string_starts_with() pcsl_string_ends_with() pcsl_string_index_of() pcsl_string_index_of_from() pcsl_string_last_index_of() pcsl_string_last_index_of_from() pcsl_string_trim_from_end() pcsl_string_trim() pcsl_string_convert_to_jint() pcsl_string_convert_from_jint() pcsl_string_convert_to_jlong() pcsl_string_convert_from_jlong() pcsl_string_free() pcsl_string_get_utf8_data() pcsl_string_release_utf8_data()

Chapter 8

PCSL

71

pcsl_string_get_utf16_data() pcsl_string_release_utf16_data() pcsl_string_is_null()

You must also provide definitions for the following macros:


PCSL_DEFINE_ASCII_STRING_LITERAL_START_MD PCSL_DEFINE_ASCII_STRING_LITERAL_END_MD PCSL_STRING_LITERAL_LENGTH_MD PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_START_MD PCSL_DEFINE_STATIC_ASCII_STRING_LITERAL_END_MD PCSL_STRING_NULL_INITIALIZER_MD

Porting Unicode Resource Names


MIDP (including PCSL) allows Unicode symbols to be used in RMS resource names. These Unicode symbols may also be used in Sun Java Wireless Client software file names. If your platform does not accetp Unicode characters, you must convert the Unicode symbols to ASCII and then substitute the ASCII symbols in place of Unicode in the file names you port. The engineer porting the Sun Java Wireless Client software can choose the way Unicode resource names are transformed into ASCII file names. The default encoding system used by the Sun Java Wireless Client software is radix 41 encoding. It should be suitable in most porting cases.

Note Other encoding schemes are possible. To use a different encoding scheme
(for example, radix 64 or radix 85), reset the build flag ESCFILENAMES_MODULE= radix41 at build time to the new radix scheme. For more information, see the Build Guide. Conversion of Unicode symbols to ASCII characters is done by the PCSL subsystem pcsl/escfilenames. For specific information about radix 41 encoding: 1. Find the file pcsl/escfilenames/radix41/pcsl_esc_md.h.

72

Architecture and Design Guide December 2008

2. Find the definition of macro PCSL_ESC_MOREDIGITS_MD. The ASCII characters shown here are the ones that will be used as digits in place of Unicode encoding. For more information, see About Radix 41 Encoding on page 73. The radix 41 encoding scheme also uses a number of escape characters. These escape characters can be used to escape a specific sequence of characters (for example, to escape non-English characters, such as Chinese or Korean). All escape characters are defined via Sun Java Wireless Client software macros. To find valid escape characters: 1. Find the file pcsl/escfilenames/radix41/pcsl_esc_md.h. 2. Find the following macros:

PCSL_ESC_SHIFT_TOGGLE_MD PCSL_ESC_SHIFT1_MD PCSL_ESC_PREV_BLOCK_MD PCSL_ESC_TOGGLE_MD PCSL_ESC_FULL_CODES_MD

Note Escape symbols must not be used as digits.

About Radix 41 Encoding


Radix 41 encoding uses 41 digits to replace Unicode symbols. The first 10 digits are the numbers 0-9. The next 26 digits are the letters of the English alphabet, a-z. In total, this makes up 36 digits. The last five digits (to make 41) come from the first five digits shown in the macro PCSL_ESC_MOREDIGITS_MD.

Note The other symbols shown in the macro PCSL_ESC_MOREDIGITS_MD are not needed for radix 41 encoding, but may be used for other radix encoding schemes (for example, radix 64 or radix 85).
Other radix encoding schemes are defined in the macro ESCFILENAMES_MODULE, in the same location as the other macros. If you change the default setting for the build flag ESCFILENAMES_MODULE=radix41, the macro ESCFILENAMES_MODULE is referenced for the new radix scheme.

Chapter 8

PCSL

73

Encoding for Non-English Resource Names


If the default encoding scheme provided by radix 41 is not sufficient for encoding non-English resource names, it is possible to define your own digits and escape characters. 1. Think out a new name for your ESCFILENAMES_MODULE. For example, you may want to call it myos (as in, my OS). 2. Choose the radix scheme you want to use. Your choices are 16, 51, 64, and 85. 3. Copy the directory corresponding to the chosen radix under the new name. For example: $ cp -r radix16 myos 4. In the file pcsl_esc_md.h modify the macros that define the digits and escape characters. 5. Run make using the new module, and using the donuts package. For example: $ make PCSL_PLATFORM=javacall_i386_vc ESCFILENAMES_MODULE=myos clean all donuts

74

Architecture and Design Guide December 2008

PutPixel Technology
PutPixel technology is a Java Wireless Client software implementation of the graphics, image, and font portions of the MIDP specification. PutPixel technology provides a quick and easy means to get graphics, image, and font functionality running during the porting process. PutPixel technology implements all of the MIDP graphics, image, and font APIs, however, by default it includes only a simple monospace bitmap English font. PutPixel technology supports the PNG image format and it provides optional JPEG support.

Note The reference port on the Microsoft Windows platform and the linux_fb
framebuffer are implemented using PutPixel technology.

Porting
One of the most difficult and time consuming parts of the porting process is implementing the graphics, image, and font systems. PutPixel technology provides a very simple means to get these functions up and running. Use PutPixel technology as part of the porting process and either replace it with a port to your platforms native resources as described in Chapter 10 or use it in your production product. The only porting step required to implement PutPixel technology is to define a screen buffer into which it can render. By default, PutPixel technology renders images into the screen buffer using the 16-bit RGB 565 format. The RGB 565 format allocates five bits for red, six bits for green, and five bits for blue. You can change the pixel format definition in the PutPixel technology porting interface header file gxj_putpixel.h.

Chapter 9

PutPixel Technology

75

Define the screen buffer as a pointer to either a virtual screen buffer, or directly into the hardware video buffer. Most systems use a double buffered screen buffer to avoid screen flicker. The system screen buffer is also specified in gxj_putpixel.h.

Building
To build Java Wireless Client software with PutPixel technology enabled, edit midp/src/lowlevelui/subsystem.gmk so that the value of SUBSYSTEM_GRAPHICS_MODULES is set to the value putpixel.

Testing
Once the system is up and running, you can run tests to verify the functionality. Refer to the Tools Guide for details about running the appropriate unit tests. If you decide to run your own tests, ROMize the code to reduce dependencies on other subsystems, such as the file system.

Tuning
The PutPixel technology code is highly tuned and requires no further optimization. If graphics performance seems slow, it is possible that screen buffer format definitions might not be set up efficiently. Check gxj_putpixel.h to determine if you can optimize how the system gets and sets pixel values. Performance can also be improved by replacing the default font library with the native font engine. PutPixel technology comes with a simple monospace bitmap font for ASCII characters. You can use either of the following two methods to replace it with platform font libraries:

If the platform has an API to render strings into a given destination screen buffer, port the implementation of the functions gx_draw_chars, gx_get_charswidth, and gx_get_fontinfo to use the platform font API. Replace the font bitmap with the platform font bitmap definition. The default PutPixel technology character drawing function is then used to render the bitmap.

76

Architecture and Design Guide December 2008

You can add support for JPEG graphics by obtaining the libjpeg open source library and using the Java Wireless Client software build system to build it. Specify the following options either on the gnumake command line or in build/platform/Options.gmk:

USE_JPEG=true JPEG_DIR=your-libjpeg-source-directory

Support for additional graphics formats such as GIF, and BMP is difficult to add. If additional graphics formats are required, it is best to replace PutPixel technology with a port to your platforms native resources as described in Chapter 10.

Chapter 9

PutPixel Technology

77

78

Architecture and Design Guide December 2008

10

Low-Level Graphics and Images Services


This chapter discusses the design and porting of the low-level graphics and images service and its interactions with other parts of Java Wireless Client software. To best understand this design, become familiar with the material in the following documents:

MIDP 2.1 Specification. The Java Virtual Machine Specification, Second Edition. The Java Programming Language (3rd Edition). KNI Specification, which is part of the documentation included with the CLDC Reference Implementation. See http://java.sun.com/products/cldc/.

Description
The low-level graphics and images service subsystem provides all of the low-level graphics and image functionality required by the MIDP 2.1 Specification. It has the following components:

Graphics Rendering Low-level graphics routines for Java Wireless Client software system. Graphics Context Manages the graphics context, which consists of the controlling parameters for the current graphics routines (such as line width, font selected, and so on). The graphics contexts must remain synchronized between the native platform and the Java platform. Image Handling Handles the decoding, storage, and rendering of images.

Chapter 10

Low-Level Graphics and Images Services

79

External Interactions
The low-level graphics and images service subsystem interacts with the following Java Wireless Client software subsystems:

High-level UI subsystem Gaming subsystem File System Networking OS functionality

FIGURE 10-1 shows these interactions.


FIGURE 10-1

Subsystem Interactions Game subsystem

High-level UI subsystem

Low-level graphics and image subsystem Image Primitive

Native platform APIs

Design
Java Wireless Client software provides a highly optimized low-level graphics and images service subsystem without sacrificing portability. More specifically, the subsystem must provide the following functionality:

Optimized Performance and Footprint A port must be able to use as many available native features as possible to increase performance and reduce total code size. Portability Customers must be able to replace individual components with the available platform counterparts by making clearly defined changes. Functionality Levels Customers must be able to pick the combination of components appropriate for their devices.

80

Architecture and Design Guide December 2008

For example, most devices provide at least some of the primitive graphics capabilities that match MIDPs graphics requirements. For these features, a single layer of indirection between the public APIs of the javax.microedition.lcdui package and the platform-specific graphics libraries is sufficient. However, many devices do not provide features such as drawing arcs. For these features, devices might have to depend on Java Wireless Client software to provide more code between the public APIs and the platformspecific graphics libraries. Initially, the low-level graphics and images service component targets the following types of platforms:

Platforms with some, but not all, of the rich graphics APIs required by MIDP Platforms with rich graphics APIs that are almost a one-to-one mapping to MIDP graphics APIs

Flexibility The subsystem must be easily adapted to take advantage of special platform architectures (such as devices with dual processors or hardware graphics accelerators)

Graphics Rendering Component


The graphics rendering component provides the functionality of the Graphics class. It has drawing primitives for text, images, lines, rectangles, and arcs. It also provides access to a display object (an instance of the class javax.microedition.lcdui.Display) for obtaining device characteristics, such as whether the system supports color and how many distinct gray levels are available. For a complete description of the Graphics class, refer to the MIDP 2.0 Specification.

Primitive Graphics Routines and Porting


For performance, most of the methods for drawing graphics primitives call native functions. For example, the Java method drawLine calls the corresponding nativelayer function gxpport_draw_line. The native calls go through the KVM Native Interface (KNI) before the platform routines are called. KNI combines high performance and low memory overhead. See the KNI Specification, which is part of the CLDC documentation, for more information. The use of gx_draw_line provides a common interface between PutPixel technology and platform graphics. The graphics porting layer, which uses KNI, is well defined. Each call to KNI is given the full class name followed by the method name, with an underscore (_) used as a separator. The native function itself has the prefix gxpport_ followed by the method name translated to follow the underscore naming convention. FIGURE 10-2 shows this naming convention by using drawLine as an example.

Chapter 10

Low-Level Graphics and Images Services

81

FIGURE 10-2

drawLine Method Through Its C Call

public native void drawLine(int x1, int y1, int x2, int y2);

KNIEXPORT KNI_RETURNTYPE_VOID Java_javax_microedition_lcdui_Graphics_drawLine();

extern void gx_draw_line(jint pixel, const jshort *clip, const java_imagedata *dst, int dotted, int x1, int y1, int x2, int y2);

extern "C" void gxpport_draw_line(jint pixel, const jshort *clip,gxpport_mutableimage_native_handle dst, int dotted, int x1, int y1, int x2, int y2);

Because some native platforms do not have one-to-one mapping between the MIDP API and the native API, Java Wireless Client software provides a library of drawing primitives called the Java Wireless Client software Native Platform Primitive Library (LNP). Java Wireless Client software Native Platform Primitive Library can be used to supplement missing native-platform functionality. For example, most platforms do not have an arc drawing function, so the LNP arc drawing functions provide it.

Design Rationale, Notes, and Considerations


The architecture and design of the graphics rendering component is as simple as possible to facilitate portability and performance. To maintain or improve the components performance, use as much of the native primitive capabilities as possible.

82

Architecture and Design Guide December 2008

Graphics Context Component


The graphics context component is a data structure that maintains the rendering systems property values, including those used during rendering and those that hold pointers to the rendering area. These properties must be consistent between the Java platform layer and native code for correct behavior.
FIGURE 10-3 illustrates which functions can update the graphics contexts property values and which can provide data to the graphics context through their parameters.
FIGURE 10-3

Functions That Update Property Values and Functions Providing Data Translate translate

Clip region setClip

Color setColor, setGrayscale

Affected by: clip


Font setFont Line style setStrokeStyle region and translate

Takes parameters: Affected by: clip


region, translate, and color coordinates and so on image rendering drawImage drawRegion drawRGB copyArea ... (various parameters)

Affected by: clip region


translate, color, and font

Affected by: clip region,


translate, color, and stroke style

Takes parameters:
location coordinates and unicode data drawChar drawChars drawString drawSubstring Unicode data (parameters)

Takes parameters:
location coordinates drawLine drawArc drawRect drawRoundRect

Takes parameters:
location coordinates fillArc fillRect fillRoundRect fillTriangle

Location coordinates (such as x and y) (parameters)

Detailed Design
When Java Wireless Client software executes a rendering operation (native or Java platform), it must use the most recently updated values of the properties shown in FIGURE 10-3. Because all property values are set from within the Java platform, those operations always have access to the correct values. However, the native code must make sure its values are current. You must decide on a method for synchronization and the number of native graphics contexts to use.

Chapter 10

Low-Level Graphics and Images Services

83

Synchronization Method
The native code has two ways to make sure its values are current.

Mirror all of the properties in native code Each time a Java method is called, a native call updates the corresponding native data structure. Use a dirty bit to track the property values that have changed Before a render operation, the native code queries the updated values.

Number of Native Graphics Contexts


The implementation of the graphics context component in the native layer also depends on whether multiple graphics contexts can be managed. It is likely that the native code does not keep separate graphics contexts for each Graphics instance, but the rendering area of a Graphics instance must always be stored individually. For example, consider two different cases: one in which an implementation supports only one platform-managed graphics context and another in which an implementation supports multiple graphics contexts. With only one native graphics context, a native implementation must handle the following situations:

Mapping the graphics context identifier to a graphics context structure implemented in native code Ensuring the graphics context is current Ensuring the associated property values are current

With multiple native graphics contexts, the first two steps are unnecessary. The implementation must only ensure that the appropriate graphics context is active. If the implementation mirrors all of the properties in native code (instead of using a dirty bit), the native code does not need to check whether the property values are current. Other function implementations are trivial.

Image Component
The image component is made up of the following parts:

Preprocessor Decodes input image data for immutable images. Creates and initializes image data for mutable images. Storage Manages storage of actual bits of images. Accessor Provides access to pixels of images. Handles logic to traverse the pixels. Also handles transformations. Renderer Renders image data into a specified graphics objects destination.

84

Architecture and Design Guide December 2008

FIGURE 10-4 shows the interactions of the parts of the image component.
FIGURE 10-4

Components of the Low-Level Graphics and Images Service Subsystem lcdui.Image lcdui.Graphics

Preprocessor Decoder or decoders Accessor Rendering

Storage Immutable Mutable

The image component requires access to information from the device, including bit depth, storage of transparency, alpha information, and palette handling. This information is available at compile time. It must be available from a properties or configuration file.

Preprocessor Component
The preprocessor component converts input image data into a format usable by the Java Wireless Client software. It is always used when creating Image instances. The MIDP 2.1 Specification discusses two kinds of images: mutable (images that can be changed) and immutable (images that cannot be changed). All immutable images have associated data from which the image is created. Mutable images are designed to be rendered upon. The preprocessor reads data from the specified source of immutable images and formats it. Formatting might include making copies of existing images or converting raw bitmap data into an efficient internal representation. The preprocessor initializes internal memory of a suitable size and format for mutable images. It prepares the image for rendering. The image is the destination of a Graphics instance.

Chapter 10

Low-Level Graphics and Images Services

85

Creating Immutable Images From an Image Data Source


Immutable images are always created from image data. Image data is obtained from the follow sources:

Java platform:

Input stream URL Byte array int array of ARGB values

Because data from these sources is available only from the Java platform, it must be transferred to native code before creating the image.

Native layer:

Image Image with a possible transformation, specified region, or both

Because the image was created by the low-level graphics and images service subsystem, a native representation exists that is accessible by the native code.

Native image: The ability to use a native image requires adding an API that provides nativeimage access to the Java platform layer of the low-level graphics and images service subsystem. It is an internal API. MIDlets must not be able to load images in native format. The ability to use native images is useful for two reasons:

Enhanced performance. Theme support in the high-level UI. All themes are known prior to MIDlet launch (for example, at port or installation time). Theme images can be handoptimized for storage size and or platform speed.

Every port must reimplement both the native and Java platform code of the preprocessor component. In addition, the method of specifying the URL of the native image might differ for each port.

Creating Mutable Images With a Given Width and Height


Creating mutable images differs in functionality and implementation from creating immutable ones. Because a mutable image is designed to be rendered upon, a mutable image has no source data to decode. Instead, the initial contents are always white pixels. In addition to initializing the pixels, creating a mutable image initializes the data structures for the destination of a Graphics object.

86

Architecture and Design Guide December 2008

Decoder Component
The decoder is used to create an immutable image from the bytes available from an input stream, URL, or byte array. The decoder provides a consistent interface to the decoding functions. It enables decoders for different image formats to be plugged into Java Wireless Client software easily. The decoder component makes the preprocessor extensible. The decoder is internal to the preprocessor. Its APIs are not exposed to any other parts of the low-level graphics and images service subsystem, nor to any other subsystems of Java Wireless Client software. Java Wireless Client software supports the following image formats:

PNG JPEG ARGB bitmap

FIGURE 10-5 shows the decoder architecture.


FIGURE 10-5

Decoder Architecture

Java platform layer image source: byte array, input stream, URL
int array of RGB data

Preprocessor and decoder components Native layer image sources: image, with or without a transformation mutable image

Implementing a Decoder
A Decoder for an image format can be implemented in one of two ways. The first method is to implement the decoder within the Java Wireless Client software source base. This method must be used for image formats for which a native decoder is not available. The decoder must provide the decoded image in either the native image format or a format that is supported by the rest of the image subsystems components. Storing the decoded image is done with the accessors write functions. See Accessor Component on page 89 for information.

Chapter 10

Low-Level Graphics and Images Services

87

The second method is to use a decoder implementation already on the device. This saves effort and gives the Java Wireless Client software a smaller footprint. In addition, optimizations to the decoder can be made independently because its implementation is de-coupled from the Java Wireless Client software source base. Two scenarios utilize an existing decoder. In the first scenario, the decoder decodes directly into the native image-storage format. In this scenario, using the accessor to store the decoded image might be inefficient. Instead, the storage modules APIs can be used. See Image Storage Component on page 89 for information. In the second scenario, the decoder emits the decoded image as a stream of bytes. In this scenario, the accessors methods must receive the decoded image. They set the bitmap data values for an individual pixel, a scan line, or an entire region. The decoder defines three types of errors to handle errors during decoding: those detectable before, during, and after decoding. The following list shows the errors, categorized by type:

Before decoding:

Invalid format Insufficient data Invalid sub format Malformed data Invalid memory access (implementation error)

During and after decoding:


The decoding functions can return the following values:


GXUTL_NATIVE_IMAGE_NO_ERROR GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR GXUTL_NATIVE_IMAGE_DECODING_ERROR GXUTL_NATIVE_IMAGE_UNSUPPORTED_FORMAT_ERROR

Accessor Component
The accessor provides a generic interface to access the individual pixel data of any image. It also contains all logic to handle transformations, allowing traversal of pixels in the image with transformations in effect. The accessor performs the following functions:

Traversing and reading pixel data from storage Traversing and reading pixel data with transformations in effect Writing pixel data into storage

88

Architecture and Design Guide December 2008

The following javax.microedition.lcdui.Image method uses the accessor directly:


void getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height)

Image Storage Component


Image storage manages the storage area for image data, pixel data, and related information such as color palette. Specifically, it does the following tasks:

Manages (allocates and deallocates) memory for storing images. Provides access to pointers that point to the following data:

Bitmap data Transparency information Palette information

Synchronizes a backing store for mutable images with a Graphics context. This is optional and depends on the design of the graphics context.

Image storage can store image data in one of three ways:

Native bitmap structure Using the native bitmap format saves code size and effort. The disadvantage is it is dependent on the device APIs. Native bitmap structure managed by Java Wireless Client software This option removes the dependency on the device APIs. The disadvantage is that each port must optimize the component, and optimization requires effort. Java platform byte array Allocating the bitmap data in the Java platform layer simplifies memory management. The disadvantage is that it might impact performance.

The decision on how to store different image formats requires careful consideration for every platform. Most platforms support two types of native image storage: one targeted towards rendering performance and the other towards storage compactness. A MIDP port can decide to maintain this distinction, perhaps using one for immutable images and the other for mutable images. A port can also, for simplicity, sacrifice performance by using only one image storage format. The following factors influence this decision:

Speed of rendering from image storage in different formats Speed of access to individual pixel data

Chapter 10

Low-Level Graphics and Images Services

89

Renderer Component
The renderer transfers all or some of the bits of a stored image onto the destination of a Graphics object, possibly converting the bits to the destination format in the process. Rendering is a separate part of the image component for performance. The renderer contains logic that determines the fastest code path to render bits from stored image to the graphics context. Two main paths are available: one path is for rendering an immutable image, the other for rendering a mutable image. The paths are different because the different types of images are expected to be stored in different formats.

Porting
This section discusses strategies for porting the low-level graphics and images subsystem. The low-level graphics and images subsystem provides the fundamental graphics functionality and image processing to the entire MIDP runtime system. Address this subsystem early in the porting process. If your system does not provide direct mapping for the high-level user interface subsystem (for example, provides no native platform alert or dialog), the low-level graphics and images subsystem becomes responsible for rendering all the high-level components. Therefore, you must carefully monitor performance throughout the entire porting process. The major design goals for the low-level graphics and Images and images subsystem are high performance and portability. To ease the porting effort, the porting interfaces are divided into the following groups:

Primitive graphics group Image manipulation group String and font drawing and accessing group Alert sound group Vibrate and backlight group

Each group has special porting APIs. The porting layer consists of native and C language APIs. You can choose the level at which you want to port the low-level graphics and images subsystem. For a feature for which a native porting API is available, it might be possible to implement that feature entirely in Java programming language code. However, to improve performance, use the provided native porting APIs.

90

Architecture and Design Guide December 2008

Porting the Primitive Graphics Group


The graphics porting layer, which uses KNI, is well defined. Each call to KNI is given the full class name followed by the method name, with an underscore (_) used as a separator. The native function itself has the prefix gxpport_ followed by the method name translated to follow the underscore naming convention. The use of gx_draw_line provides a common interface between PutPixel technology and platform graphics. FIGURE 10-6 shows this naming convention by using drawLine as an example.
FIGURE 10-6

drawLine Method Through Its C Call

public native void drawLine(int x1, int y1, int x2, int y2);

KNIEXPORT KNI_RETURNTYPE_VOID Java_javax_microedition_lcdui_Graphics_drawLine();

extern void gx_draw_line(jint pixel, const jshort *clip, const java_imagedata *dst, int dotted, int x1, int y1, int x2, int y2);

extern "C" void gxpport_draw_line(jint pixel, const jshort *clip, gxpport_mutableimage_native_handle dst, int dotted, int x1, int y1, int x2, int y2);

Map all the primitive graphics routines and implement them. All C native declarations of low-level primitive graphics porting routines are in the file gxpport_graphics.h. Your platform might not provide a one-to-one mapping for all the porting APIs. For routines missing from your platform, use the routines available in the Java Wireless Client software release as a reference or write your own. Refer to Drawing and Filling Arcs on page 96 for a detailed explanation of how to implement an arc drawing routine. For example, it is important to distinguish the differences between the coordinate system of your platform and that specified in the MIDP specification. Java Wireless Client software includes a description of the LCDUI APIs, which provide a detailed explanation of each of the primitive graphics porting APIs.
Chapter 10 Low-Level Graphics and Images Services 91

Porting Checklist for Primitive Graphics


Before you begin porting Primitive Graphics, step through the following checklist:

Does your platform support transparent images? How many colors does your platform support? How many transparency levels does your platform support? What is the hexadecimal value of the erase color? Does your platform support double buffering? Does your platform support a pointer or a stylus? If your platform supports a pointer, does it support pointer motion? What is the color depth that you want to support in the MIDP runtime system? Does your platform support key repeat events?

After you complete the checklist, enter the results as constants inside the configuration file. See the Chapter 4 for details about how to enter the constants in the configuration file. These constants are necessary during the compilation of MIDP. Without them, the build system might not be able to complete the compilation and errors can occur. Note that because they are needed at compile time, the ability to dynamically change these properties while MIDP is running is not supported. The following table lists the constants and descriptions related to low-level graphics. By modifying these values inside the constants configuration file, you can change the platform behavior.
TABLE 10-1 Property

Low-Level Graphics Constants


Description

DISPLAY_IS_COLOR

Set to 1 (true) when color is supported. Set to 0 (false) when color is not supported. Number of colors the platform supports, in bytes. Color depth that the platform supports, in bits per pixel (bpp). Number of alpha channel levels the platform supports. Color, in hex, used as the erase color (the color used to clear away any existing pixels from a graphics object before painting the new pixels). Set to 1 (true) when double-buffering is supported. Set to 0 (false) when double-buffering is not supported.

DISPLAY_NUM_COLOR DISPLAY_DEPTH ALPHA_LEVELS ERASE_COLOR

IS_DOUBLE_BUFFERED

92

Architecture and Design Guide December 2008

TABLE 10-1 Property

Low-Level Graphics Constants (Continued)


Description

POINTER_SUPPORTED

Specifies whether both the platform and MIDP implementation provide support for a pointer (press and release). Set to 1 (true) if you want runtime to support a pointer. Set to 0 (false) if you do not want to support a pointer. Specifies whether both the platform and MIDP implementation provides support for pointer motions. Set to 1 (true) when pointer motion is supported. Set to 0 (false) when pointer motion is not supported. Depth, in bits, of images supported by the platform. This might or might not be the same as the bit depth used by the rest of the platforms rendering system. Specifies whether both the platform and MIDP implementation provides support for key repeat. Set to 1 (true) when key repeat is supported. Set to 0 (false) when key repeat is not supported.

MOTION_SUPPORTED

IMAGE_DEPTH

REPEAT_SUPPORTED

Drawing Graphics Primitives


The Graphics class provides drawing primitives for text, images, lines, rectangles, and arcs. This section describe the graphics coordinate system, and how that affects the drawing of lines, rectangles, and filled rectangles. It also explains the requirements of drawing arcs.

Coordinate System Overview


A Graphics object has a coordinate system with its origin at the upper-left corner of the destination. The X-axis direction is positive towards the right, and the Y-axis direction is positive downwards. The coordinate system and graphics implementation in the Java Wireless Client software assume that the device has square pixels. If your device does not have square pixels, you must modify the lowlevel graphics and Images subsystem to take the different pixel shape into account. An application must be able to rely on horizontal and vertical distances being equal on the device display. The coordinate system represents locations between pixels, not the pixels themselves. The first pixel in the upper left corner of the display lies in the square bounded by coordinates (0,0), (1,0), (0,1), and (1,1). This is shown in the following figure.

Chapter 10

Low-Level Graphics and Images Services

93

FIGURE 10-7

Graphics Class Coordinate System

First pixel in the upper left corner

Drawing Lines
A Graphics object must draw a line between the coordinates (x1,y1) and (x2,y2). In the coordinate system, that means that the line begins below and to the left of (x1,y1), and ends below and to the left of (x2,y2). This is shown in the following figure, which shows a line drawn from (2,2) to (6,6).
FIGURE 10-8

Drawing a Line

First pixel is below and to the right of coordinate (2,2)

Last pixel is below and to the right of coordinate (6,6)

94

Architecture and Design Guide December 2008

Drawing and Filling Rectangles


A Graphics object draws and fills rectangles such that a drawn rectangle is one pixel larger than a filled rectangle of the same requested height and width. That is, the MIDP 2.1 Specification says that the drawRect method, Draws the outline of the specified rectangle... The resulting rectangle will cover an area (width + 1) pixels wide by (height + 1) pixels tall. In contrast, the fillRect method fills the specified rectangle with the current color. For an example, see FIGURE 10-9.
FIGURE 10-9 shows two rectangles. The rectangle on the left shows the drawRect method drawing a rectangle starting at (0,0) with a width of 8 and height of 6. The rectangle on the right shows the fillRect methods rectangle that starts at (0,0) and has a width of 8 and height of 6. That is, they correspond to the following calls:

drawRect(0, 0, 8, 6); fillRect(0, 0, 8, 6);


FIGURE 10-9

Drawing Compared With Filling a Rectangle

Drawing and Filling Arcs


It can be difficult to understand the contract that the drawArc method must fulfill. This section explains its requirements. Note that the methods that draw and fill arcs have the same size relationship as that described in the previous section (Drawing and Filling Rectangles on page 95). To draw an arc means to draw all or part of an ellipse. The mathematical definition of an ellipse is:
x2/a2 + y2/b2 = 1

Chapter 10

Low-Level Graphics and Images Services

95

The value of the variable a controls the width of the ellipse, and the value of the variable b controls the height. If a = 2 and b = 1, the ellipse is twice as wide as it is high. It looks like this:
FIGURE 10-10

Ellipse

b a

If a and b have the same value, the equation reduces to a circle:


(x2 + y2)/r2 = 1

The image is a circle as shown in FIGURE 10-11:


FIGURE 10-11

Circle

b a

The drawArc method specification says: Angles are interpreted such that 0 degrees is at the 3 oclock position. A positive value indicates a counter-clockwise rotation while a negative value indicates a clockwise rotation. The specification uses the common convention that 0 degrees lies where the circle crosses the positive x axis (sometimes referred to as 3:00 like in the specification). Positive degrees lie with the positive values on the y axis (they go counterclockwise) and negative degrees lie with the negative values on the y axis (they go clockwise). The following figure shows the angles at 0, 90, and -90:

96

Architecture and Design Guide December 2008

FIGURE 10-12

0, 90, and -90 Degrees on a Circle

y axis 90o 0o x axis

-90o

The specification then says: The center of the arc is the center of the rectangle whose origin is (x, y) and whose size is specified by the width and height arguments. The drawArc method has x, y, width, and height as four of its arguments. Remember that the coordinate system of a canvas has its origin (0,0) at the upper left corner, the numeric values of the x-coordinates monotonically increase from left to right, and the numeric values of the y-coordinates monotonically increase from top to bottom. To draw an ellipse, the value of the variable a in the ellipse equation must be w/2 and the variable b must be h/2. The center of the ellipse must be at (x+(w/2), y + (h/2)). Using these values creates an ellipse that is centered within the rectangle, as specified by the method description. The ellipse is also tangent to the rectangle at four points, which are the minimum and maximum radii of the ellipse. The ellipse is specified by the rectangles width and height arguments, as specified by the method description. The following figure shows a canvas with an arc that meets these requirements. The arc is a full ellipse. The figure shows the ellipse within the rectangle mentioned in the specification. The rectangle is shown with a dashed line because it is not actually drawn on the canvas. The rectangles width is represented by the variable w, and its height is represented by the variable h.

Chapter 10

Low-Level Graphics and Images Services

97

FIGURE 10-13

Boxed Ellipse

Canvas origin (0, 0)

(x, y) b (h/2) h a (w/2) w Center of ellipse (x+(w/2), y +(h/2)) (x+w, y+h)

The final part of the specification covers what happens when the method is asked to draw only part of the ellipse. It says: The angles are specified relative to the non-square extents of the bounding rectangle such that 45 degrees always falls on the line from the center of the ellipse to the upper right corner of the bounding rectangle. As a result, if the bounding rectangle is noticeably longer in one axis than the other, the angles to the start and end of the arc segment will be skewed farther along the longer axis of the bounds. In a circle, the angles are not skewed, as shown in the 45 and -120 degree angles in the following figure:
FIGURE 10-14

45 and -120 Degrees on a Circle 45o

-120o

98

Architecture and Design Guide December 2008

Skewing appears when the circle is stretched into an ellipse, as shown in the following figure. The point that was 45 degrees on the circle is shifted so the angle of the line from the center to that point is no longer 45 degrees. Technically, 45 degrees of arc exists between the x axis and the labeled spot, but on paper the angle of the line from the center to that point is not really 45 degrees.
FIGURE 10-15

45 and -120 Degrees on an Ellipse 45o

-120o

A port of this method must work the same way: It must use the start and end points of a partial arc as though the ellipse were a circle. To make sure that the skewing happens correctly, the MIDP 2.0 Specification requires that 45 degrees always falls on the line from the center of the ellipse to the upper right corner of the bounding rectangle, as shown by the circle and ellipse in the following figure. The figure again shows the bounding box with a dashed line. The figure also extends the 45-degree line so that it touches the box.
FIGURE 10-16

Boxed Circle and Ellipse, With a 45 Degree Angle

The (x,y) coordinates of a point on a circle are calculated using sine and cosine. The (x,y) coordinates of the point at d degrees on a circle of radius r is:
(x = cos(d)*r, y = sin(d)*r)

For example, on a circle where r = 1, the (x,y) coordinates for the point that is at 30 degrees are (cos(30), sin(30)). The equation for the corresponding point at d degrees on an ellipse with axes a and b is (x = cos(d)*a, y = sin(d)*b).

Chapter 10

Low-Level Graphics and Images Services

99

Drawing and Filling Rectangles With Rounded Corners


Drawing and filling rectangles with rounded corners combines the previous two topics, drawing rectangles and drawing arcs. The difference between drawing and filling a rectangle with rounded corners is one pixel in height and width, as discussed in Drawing and Filling Rectangles on page 95. A MIDlet draws a rectangle with rounded corners by specifying not only the starting pixel, the height, and the width of the rectangle, but also the width and height of the arc to use to round the corners. The following figure shows a rectangle drawn with round corners using the call drawRoundRect(0, 0, 30, 40, 4, 3). That is, the rectangle starts at the upper left corner, and is 30 (+1) pixels wide, 40 (+1) pixels high, with corners rounded with an arc that is four pixels wide and three pixels high.
FIGURE 10-17

Drawing a Rectangle With Rounded Corners

Arc is four pixels wide

Arc is three pixels high

Porting Image Manipulation Group


The image component of the low-level graphics and images subsystem implements the javax.microedition.lcdui.Image class. This section explains how to port this class to work on your device by interfacing the Java platform code with the native platform functions that are available.

100

Architecture and Design Guide December 2008

Mutable and Immutable Images


There are two types of images: mutable and immutable. These two types differ largely in their implementation, even though public APIs do not distinguish between the two. The following sources that create an immutable image:

Image object Image object, either a region or transformed 32-bit ARGB data Image data in one of formats supported by Java Wireless Client software (PNG and JPEG)

Immutable images are used only as a source of rendering, meaning they are used to render into the destination of a Graphics object as parameters to either the Graphics.drawImage or Graphics.drawRegion method call. Immutable images can be used within Alert, Choice, Form, or ImageItem objects. They can also be used as sources for Sprite and TiledLayer objects. You must be careful to ensure that the implementation of the classes that use immutable images as a source is compatible with the native format for immutable images. For example, the implementation of ImageItem, if it uses a native component, must be able to use the native peer of an immutable image for reasons of efficiency. Mutable images are intended to be used to render upon. By calling the method Image.getGraphics on a mutable Image, a Graphics object is obtained whose destination is the mutable image. Mutable images can be used within Alert, Choice, Form, or ImageItem objects. When this is done, it behaves as if a snapshot of the image is taken at set time. Refer to Alert Sound Group on page 108 in this chapter for more details. For detailed information on ChoiceGroup, Form, and ImageItem, see Chapter 12. Mutable images can also be used as sources for Sprite and TiledLayer objects. In these cases, the contents must reflect the current state of the Image at render time. For the sake of speed, the port must ensure that it is efficient for the internal storage of the mutable image to act as the destination of a Graphics object. Mutable images are always created empty (for instance, white pixels) and are not associated with any alpha channel.

Image Creation APIs


The following javax.microedition.lcdui.Image methods use the preprocessor module of the image component to create immutable images:

public static Image createImage(Image source)


Chapter 10 Low-Level Graphics and Images Services 101

public static Image createImage(String name) public static Image createImage (byte[] imageData, int imageOffset, int imageLength) public static Image createImage (Image image, int x, int y, int width, int height, int transform) public static Image createImage(InputStream stream) public static Image createRGBImage (int[] rgb, int width, int height, boolean processAlpha)

The Image method uses the preprocessor module of the image component to create mutable images:
public static Image createImage(int width, int height)

Image Formats
MIDP 2.0 APIs for getting pixel data and creating images from RGB data use a 32-bit ARGB format (eight bits for alpha and eight bits per channel RGB). This format might be inefficient to use in a device. If it is inefficient, the decision on the internal format of the images depends on several factors:

Make mutable images as similar as possible to those provided by the hardware. The storage format of mutable images must not require conversions at render time. Mutable images can be widely used by the platform and the applications as an Image buffer, thus making performance critical. Mutable images need not support transparency and alpha. By calling getGraphics on an image it is possible to obtain a graphics object that renders to the mutable image. If the format of a mutable image is supported by the hardware, rendering into this image is efficient. Match the storage format for immutable images as closely as possible to the native representation. However, immutable images are used only as the source for rendering. Therefore, if this code path is optimized, space-saving formats can be used for storing immutable images. For example, a 1-bit black-and-white PNG image does not need to be converted to a 15-bit color image for rendering if the rendering code for the 1-bit image is optimized. Immutable images must support alpha channel. Depending on the ports requirements, the image format must be chosen to satisfy the platforms performance and space requirements.

102

Architecture and Design Guide December 2008

Transparency and Alpha


The MIDP 2.1 Specification supports transparency in Portable Network Graphics (PNG) images. See http://www.w3.org/Graphics/PNG/ and http://www.libpng.org/pub/png/ for more information on Portable Network Graphics. Transparency might exist only in immutable, off-screen images created from PNG images or created from arrays of ARGB (alpha, red, green, blue) data. Moving an image that contains transparency data into a mutable Image instance (rendering it) changes the data into a native, opaque format and the transparency information is lost. One way an image can encode transparency is by designating one or more pixel colors as transparent. Any pixel with the specified color is treated as fully transparent. For PNG images, this is implemented using a tRNS chunk. Another way that an image can encode transparency is by including an alpha value with each pixel. This is ARGB (alpha, red, green, blue) data. For a black and white image, eight bits encode a pixels alpha value (00000000 is transparent and 11111111 is opaque), and eight bits specify its color (00000000 is black and 11111111 is white). For a color image, some number of bits encode a pixels alpha value (all ones is fully opaque, all zeros is fully transparent, and values in between are semi-transparent) and the same number of bits specify the red, blue, and green elements of each pixel. The number of bits is usually eight or 16. Java Wireless Client software uses eight. However, decoding images with 16-bit alpha channel is supported, and the resulting image has an alpha channel that is sampled down to 8 bits. An image can also use a palette alpha encoding technique that provides image data that specifies the color of each pixel, and a chunk that specifies alpha values for corresponding RGB values (a PLTE chunk). A MIDP 2.0 compliant implementation must be able to render full transparency. That is, it must treat pixels with an alpha value of zero (or the color in a tRNS chunk) as fully transparent, and must treat pixels with alpha values greater than zero as nontransparent. The MIDP implementation might choose to treat non-transparent pixels as opaque or to implement alpha blending, a technique that renders non-transparent pixels in a way that shows some of whatever is behind them. A MIDP implementation that supports alpha blending can use either of two techniques to interpret non-transparent pixels:

It can composite the non-transparent bits against the pixels on the screen. This provides the best looking image, but takes a lot of processing. Java Wireless Client software uses this technique. It can composite the non-transparent bits against some color, such as white. This provides a good-looking image, and less processing is required. This technique is not used by Java Wireless Client software.
Chapter 10 Low-Level Graphics and Images Services 103

However you support transparency in your port, follow this general rule: Process transparency data at decode time, for these reasons:

You have all the information at that time, so it is easier to make the picture look as its creator intended it. You might be able to combine processing steps to improve the look of the image while decreasing processing time.

Note that the storage format, including the alpha channel, has an effect on the performance of the following functions:

Creating Rendering Accessing (getRGB and sprite collision checking)

Transformations and Region Rendering


If the target device supports the transforming of images at render time, this capability is easily exploited by the architecture of the image subsystem (the function renderRegion for both mutable and immutable images must be ported to take advantage of this fact). However, if support for renderRegion is not provided, all the transformation code must be written at porting time. Implementing transformed rendering involves the following high-level steps: 1. Set up pointers to the source data. 2. Obtain pixel data. 3. Convert to a renderable format if necessary. 4. Render to the destination. This process is much faster in cases where pixel data is easily traversable and conversions are not necessary.

Porting Checklist for the Image Manipulation Group


Prior to porting the low-level graphics and image subsystem, use the following checklist to determine if porting requirements for the image component are met:

What image types are provided by the platform? What are the supported color depths? Is access available to the internal pixel data of the images? What is the format for the source data used for image creation? If more than one type of image is provided, is conversion between them possible?

104

Architecture and Design Guide December 2008

Are transformations possible on images at render time or at creation time? How is transparency information stored? What type of transparency or alpha is most efficient when using this platform? Is transparency information maintained when the image is transformed? Are different types of images optimized for different uses? For instance, one type might be for image storage, another for portability, and another for images where speed is critical. Be sure that your images follow as close as possible to the service hardwares native format.

Functions to Port
The following files in midp/src/lowlevelui/platform_graphics_port/include directory contain the declarations of platform-specific Image functions:

gxpport_immutableimage.h gxpport_mutableimage.h

Platform-specific implementations of Image functions are in the directory midp/src/lowlevelui/platform_graphics_port/port.

Facilitating Porting of the Image Manipulation Group


Following these steps facilitates the porting process: 1. Create a mutable image with createImage(int width, int height). Design and implement storage of a mutable image. The implementation must pass the following tests:

Run getWidth and getHeight. The correct values must be returned. Render the created image to screen. White pixels must be rendered.

2. Provide a graphics object that renders to a mutable image. Provide functions to create a Graphics object that renders to a mutable image. The implementation must pass the following tests:

Render the mutable image to screen. White pixels must be rendered. Render graphics primitives to the Graphics object obtained from the mutable image. Render the image to the screen. The mutable images contents must show the primitives rendered onto it.

Chapter 10

Low-Level Graphics and Images Services

105

3. Create immutable image from mutable image. Design and implement storage for immutable images. The implementation must pass the following tests:

Get properties for immutable images. Render an ImmutableImage to screen. Must show content that is the same as the mutable image used as source.

4. Implement createRGBImage. The following results must be achieved from this step:

Design storage of alpha channel data and transparency values in immutable images. Design and implement passing of large amounts of data from Java programming language code to native code. Create immutable images from the data available from the Java programming language resource. The implementation must pass the following test: Image creation meets the required performance goals.

5. Render transparent images. Implement transparency and alpha blending at render time if the platform supports it. The implementation must pass the following tests:

Render transparent images and alpha blending on a Graphics object whose destination is a mutable image. Render transparent images and alpha blending on a Graphics object whose destination is a screen.

6. Access pixel data of images with getRGB. Implement functions to access pixel data of mutable images and implement functions to access the pixel data of immutable images. The implementation must pass the following tests:

Pixel data of created mutable image must be opaque white. Pixel data of immutable images with alpha channel must return appropriate alpha values.

7. Create image from PNG and JPEG data. Implement the interface to the PNG decoder and implement the interface to the JPEG decoder. The implementation must pass the following tests:

Match the pixel data of created images with the source image. Decode source images with a color depth greater than the target system to a lower color depth appropriately. Decode alpha and transparency information of the source image correctly.

106

Architecture and Design Guide December 2008

8. Render regions of images. Render regions of immutable and mutable images with alpha blending. The implementation must pass the following tests:

Render regions of images correctly. Meet performance goals.

9. Create transformed images from source image. Implement transformations for image creation. The implementation must pass the following tests:

Implement all eight transformations specified in the MIDP 2.0 specification. Maintain alpha channel correctly when image is transformed.

10. Render transformed regions of images Implement transformations for rendering. The implementation must pass the following tests:

Achieve correct implementations of transformations. Achieve correct alpha blending of transformed regions. Meet performance goals.

String and Font Drawing and Accessing Group


Working with a user interface designer, decide which font to map to the MIDP font. Three variables are involved in choosing a suitable font between your platform and the MIDP specification: style, size, and face. Once you decide on the mapping, you can start porting font-related APIs defined in gxpport_font.h and gxpport_graphics.h. Follow the example for the Microsoft Windows platform and the Texas Instruments OMAP730 development board. Be sure that your porting code sets up and returns the font that you chose. See TABLE 10-1 for a detailed explanation of the string and font porting APIs.

Note This discussion pertains to the font used when drawing on the canvas. Do
not confuse this font with the Java Wireless Client software platform component font, which is specific for the native high-level component in the Microsoft Windows platform and the Texas Instruments OMAP730 development board.

Chapter 10

Low-Level Graphics and Images Services

107

Alert Sound Group


Map your platform sound to the MIDP alert sound. There are five types of alert sounds: ALARM, CONFIRMATION, ERROR, INFO, and WARNING. You are not required to have a unique sound for each type. However, be sure to at least distinguish ERROR from the rest of the sound types. The porting interface is defined in the anc_audio.h file in the directory midp/src/highlevelui/annunciator/include/. It is defined as anc_play_sound (int soundType).

Tip You can also use the Mobile Media API (MMAPI) if you plan to port it. When
you are done porting MMAPI, you can take advantage of its capabilities and have a richer sound for Alerts. You can start by removing the native porting interface and calling the MMAPI sound API in Display.jpp in the following directory: midp/src/highlevelui/lcdui/reference/classes/javax/microedition/ lcdui Be careful regarding how many channels you intend to occupy as a platform usually supports a limited number of audio channels at any given time.

Vibrate and Backlight Group


The platform-specific functions for the vibrate and backlight group are described in this section.

Backlight Control Methods


Devices that support display illumination can provide MIDlets with the ability to flash the devices light source through the Display.flashBacklight method defined in the MIDP 2.0 specification.

Backlighting Porting Interface


The low-level graphics and images subsystem accesses the devices backlight through the interface defined in the anc_indicators.h file in the directory midp/src/highlevelui/annunciator/include. The required function interface, anc_show_backlight, is shown in example CODE EXAMPLE 10-1:

108

Architecture and Design Guide December 2008

CODE EXAMPLE 10-1

midpLCDUIShowBacklight Interface

/** * Control the devices backlight. Turn it on or off, * toggle it, or check to see if control of the backlight * is supported by the system without changing the lights * state. * * @param mode BACKLIGHT_ON to turn on the backlight, * BACKLIGHT_OFF to turn off the backlight, * BACKLIGHT_TOGGLE to toggle the backlight, and * BACKLIGHT_IS_SUPPORTED to see if the system * supports this function without changing the * state of the backlight. <code>mode</code> * values not listed above are ignored. * @return KNI_TRUE if the device supports backlight * control or KNI_FALSE otherwise */ jboolean anc_show_backlight(int mode)

This is the only method that must be implemented for the backlight control to be supported by a new platform.

Strategies for Porting Backlighting


The implementation code for the backlight function is in the anc_model_indicator.cpp file in the midp/src/highlevelui/annunciator/platform_model/native directory. It uses device-specific library methods to toggle the backlight. Changing the implementation to use the backlight control APIs of the new device is all that is required when porting this feature of MIDP to a new target platform. If the target device does not have a backlight or if control of the light from a Java programming language application is not desired on the system, implement the anc_show_backlight method and return KNI_FALSE as shown in CODE EXAMPLE 10-2:

Chapter 10

Low-Level Graphics and Images Services

109

CODE EXAMPLE 10-2

midpLCDUIShowBacklight Interface Without Backlight Control

/** * An example anc_backlight implementation for a device * that does not support backlight control. */ jboolean anc_show_backlight(int mode) { (void) mode; return KNI_FALSE; //not supported: always return false }

Backlighting Duration
Few devices have system interfaces for illuminating or flashing screen lighting for a set duration. Because of this, the interface to the backlight is defined as a simple toggle. Brightness of the on state of the display light is left to the platform, and timing of the flash frequency or duration of illumination is done in the higher-level Java platform library code. If the native timing of the flash rate or the duration of the call is desired, or if it is provided by a system API, the code from the Java platform layer for the backlight control can be removed to reduce code size. You can find this code in the com.sun.midp.lcdui.DisplayDeviceAccess class, which deals with timing the on and off toggles of the backlight.

Vibration Control Methods


Systems that vibrate as a user alert mechanism can provide MIDlets the ability to control the devices vibrator through the Display.vibrate method.

Vibration Porting Interface


The low-level graphics and images subsystem accesses the systems vibrate mechanism through the interface defined in the anc_vibrate.h file in the directory midp/src/highlevelui/annunciator/include. The two necessary function interfaces anc_stop_vibrate and anc_start_vibrate are shown in the following code examples:

110

Architecture and Design Guide December 2008

CODE EXAMPLE 10-3

Starting Vibration

/** * Vibrate porting function: Stop vibration. * * Platform must stop the vibration at once when * this function is called. * @return KNI_TRUE when the system supports * vibrate control via this function, * KNI_FALSE otherwise */ extern jboolean anc_stop_vibrate(void);

CODE EXAMPLE 10-4

Stopping Vibration

/** * Vibrate porting function: Start vibration. * * Platform must start the vibration at once when * this function is called. * * @param duration duration of the vibrate period. * @return KNI_TRUE when the system supports * vibrate control via this function, * KNI_FALSE otherwise */ extern jboolean anc_start_vibrate(int duration);

These are the only methods that must be implemented for the Java platform vibrate control to be supported on a new platform.

Vibration Support
The system libraries to access vibration support on some devices might not exactly match the porting APIs. If they provide simple on and off or toggle support of the system vibrator, the cycle duration tracking can be handled with a wrapper of native timer code around the vibrate API. For an example of timer support written in the Java programming language, see the flashBacklight code in the class com.sun.midp.lcdui.DisplayDeviceAccess.

Chapter 10

Low-Level Graphics and Images Services

111

Network Indicator
The platform must provide users with some type of visual indication of the network usage when using the transport mechanisms specified in the MIDP 2.0 specification. The specification does not mandate how this visual indication must be implemented. It is up to the platform to use the most effective means available to indicate any network activity in a user-friendly manner. This could be done either as an icon on the devices display or by other visual means, such as controlling an LED on the device, if available. Controlling whether or not to compile the network indicator code is easy in Java Wireless Client software. If your platforms networking call already controls an indicator of some kind, you can simply set the property USE_NETWORK_INDICATOR to false in the makefile located in installDir/build/platform-model/Options.gmk. Code relating to the network indicator is not compiled. Otherwise, you can use your platforms own implementation for the network indicator. The interface can be found in the header file, anc_indicators.h in the workspace. Look for the following text:
void anc_set_network_indicator(MIDPNetworkIndicatorState status);

The network indicator has three states: indicator on, indicator off, and toggle. Be sure that the platforms implementation checks the status and sets the indicator to the correct state.

Tip Even when in full-screen mode, it is the platforms responsibility to provide


users with a visual indication of network usage.

Porting Strategies
Follow these general strategies for porting the low-level graphics and images subsystem:

Port incrementally. Work on each porting area one at a time. Do not try to port all the functions simultaneously, which makes debugging difficult. Port by example. You can start by looking at the Java Wireless Client software ports for the Microsoft Windows platform and the Texas Instruments OMAP730 development board included in the release. Verify each step. Create some simple demonstrations. For example, create a MIDlet that draws a fill box using the whole screen area. Use these small demos to verify each step during the porting process.

112

Architecture and Design Guide December 2008

When you create the demonstration MIDlets, make sure they use only those features that have already been ported, such as the CLDC and the Basic System Event.

Porting Issues
This section discusses the following porting issues:

Porting verification Error checking Boundary cases Performance tuning

Porting Verification
To verify that your porting operation is successful and completed correctly, you can perform the following actions during the porting process:

Use some simple MIDlets to validate correct behavior Use some of the interactive TCK tests on low-level graphics and Images

Error Checking
Error checking routines are usually run prior to calling the porting API. Therefore, it is not necessary for the porting implementation to check for all error conditions. For example, in the porting API for drawing rectangle, gxpport_draw_rect, you do not need to check if the width or height is less then zero as the calling routine already checks them. Refer to the header file for a detailed explanation and assumptions, if any. Note, however, that if you directly implement the Java programming language interface, rather than using the porting API, you must check for errors passed from the Java platform layer.

Boundary Cases
A mismatch between the MIDP coordinate system and your platform might occur. Pay special attention to those boundary cases where the parameters being passed in have the values 0, 1, 2, or negative numbers. For example, your platform rectangle

Chapter 10

Low-Level Graphics and Images Services

113

drawing routine might not draw anything when the height and width parameters are both 1 (that is, your platform coordinate system is inclusive). However, MIDP specifies that a single pixel might be affected.

Performance Tuning
To provide optimal graphics performance, the platform must provide a one-to-one mapping of APIs among low-level graphics drawing routines in the native platform, if possible. Ideally, a single call in the Java platform layer of a line drawing only requires one KNI call into the native layer. It then calls the platform function directly. Consider reimplementing your platform library to add libraries that directly match those in the porting APIs (or directly map to the MIDP API) as it substantially increases your platforms performance and reduce the porting effort.

114

Architecture and Design Guide December 2008

11

Implementing the High-Level UI Using Adaptive User Interface Technology


This chapter describes how to port the high-level user interface using Adaptive User Interface Technology software (AUI Technology software). AUI Technology software (formerly known as project Chameleon) is a Java technology-based user interface implementation that allows for extensive visual customization and visual skinning. AUI Technology software is used to rapidly deploy a high quality MIDP LCDUI implementation that closely mimics your devices native look and feel. This allows a deployment to forego the expensive process of porting LCDUI to the devices native platform. AUI Technology software allows user interface components such as the title bar, screen background, soft buttons, and higher-level components to be skinned in a way that closely resembles the devices native counterparts. The end result is a user interface in which Java technology applications are nearly indistinguishable from the devices native applications. AUI Technology software saves time and effort in reaching compliance with the MIDP 2.1 specification, and saves time with quality assurance and performance testing.

Design
AUI Technology software is implemented in the following Java programming language class packages:

javax.microedition.lcdui.* com.sun.midp.chameleon.*

Chapter 11

Implementing the High-Level UI Using Adaptive User Interface Technology

115

The javax.microedition.lcdui.* package contains the implementation of the MIDP LCDUI components such as Gauge, ChoiceGroup, and StringItem. AUI Technology software handles the rendering of these components and allows you to easily configure the look and feel of the components by setting properties. The com.sun.midp.chameleon.* package contains the foundation AUI Technology software implementation. The chameleon class package is organized in the following manner:

com.sun.midp.chameleon This is the top-level chameleon implementation package. In general, this package contains only high level screen constructs, such as basic layers, windows, and the paint logic for those objects.

com.sun.midp.chameleon.input This package contains the chameleon text input support classes as well as the chameleon default input method implementations, such as numeric, alphanumeric, and symbol.

com.sun.midp.chameleon.layers This package contains the chameleon concrete layer implementations, such as SoftButtonLayer, TitleLayer, and TickerLayer. These layers are combined to form a window, such as the MIDPWindow class.

com.sun.midp.chameleon.skins This package contains the skin definition classes. A skin class for each skinnable entity exists in AUI Technology software. Each class defines the skins properties, what they do, and their possible values. A good way to understand AUI Technology softwares capabilities is to read the API documentation for this package.

com.sun.midp.chameleon.skins.resources: This package contains the resource classes associated with each skin in the skins package. The resource classes define property identifiers that the skin classes use to retrieve resource values from the system. This package also contains the file skin.xml, which contains values for all the resource identifiers in the system. Properties configured in this file are ROMized at build time by the SkinROMizationTool. The SkinROMizationTool generates a file called RomizedSkin.java. Never edit RomizedSkin.java directly. For more information on the skin.xml file, see the Sun Java Wireless Client Software Skin Authors Guide to Adaptive User Interface Technology. For more information on the SkinROMizationTool, see the Sun Java Wireless Client Software Tools Guide.

116

Architecture and Design Guide December 2008

Customization
AUI Technology software provides for a great deal of customization through the configuration of properties. The complete list of properties and their functions can be found in the Skin Authors Guide to Adaptive User Interface Technology. This section describes how and where to apply property changes.

Property Loading and Skin Customization


The AUI Technology software is designed to support dynamic skin changes, allowing the user to change the look of the device on the fly. However, currently, AUI Technology software only supports a single static skin that mimics the devices native look and feel. Skin properties are compiled statically at build time. Although this can be time consuming, system startup performance is greatly enhanced by having the properties compiled at build time and not read from an external property file each time the VM is started. The configurable AUI Technology software properties can be found in following directory:
midp/src/highlevelui/lcdlf/lfjava/classes/com/sun/midp/chameleon/ skins/resources

Modify the file named skin.xml in midp/src/configuration/configuration_xml/platform/ to customize the adaptive user interface default skin. After reading and understanding the Skin Authors Guide to Adaptive User Interface Technology, you can apply changes to the skin.xml file. The system must then be rebuilt to test those changes.

Image Usage and Support


The skinning functionality in AUI Technology software has extensive and flexible support for images. Images can be in any format supported by the image decoder, such as PNG, and raw. Images can be loaded at runtime from the file system or ROMized into the deployment bundle and used directly out of memory. The following sections describe advantages and disadvantages to each of these approaches.

Chapter 11

Implementing the High-Level UI Using Adaptive User Interface Technology

117

Compressed Images Compared With Uncompressed Images


A trade off between speed and size must be made when processing images. Compressed images (such as PNG and raw images) can be used in AUI Technology software but they require decoding at startup, which imposes a performance penalty. Uncompressed images (such as raw platform format, and bmp) can also be used, but these formats create a much larger footprint on disk or in the ROM image. If resources permit, performance is improved by using an uncompressed format and tiling images using small image tiles. Typically, the port stores the skins images in the platforms native format. This way no time is spent decoding images when they are loaded, regardless of whether they are stored in the file system or in the ROM image itself.

ROMized Images Compared With File System Images


As mentioned previously, AUI Technology software supports the loading of images from either the local file system or directly from the ROM image. One advantage of using the local file system is that during development, images can quickly be replaced for testing without rebuilding the ROM image. However, if the system supports the creation of images using memory directly referenced in the ROM image, ROMizing the images in the platforms native format provides the best performance. This option requires more storage space because the image data is uncompressed and stored entirely in the ROM image. Uncompressed ROMized image data is typically much larger, but if sufficient storage is available, the performance gain is well worth the trade-off. Another aspect to consider is the types of memory being used by the platform. The file system might be implemented on slow flash memory, while the ROM image is located in faster memory. The opposite may also be true. It is possible that reading and decompressing an image from fast memory is faster than reading an uncompressed image from slow memory.

Storing Image Resources in the File System


Images stored on the file system can be in PNG or raw formats. When you assign an image to an AUI Technology software property in skin.xml, the image name is specified without an extension. When the AUI Technology software loads an image at runtime, it first attempts to load this image from the ROM image. If the load attempt fails (because the image is not ROMized), AUI Technology software adds the .png extension to the image name specified in skin.xml, and then tries to load the file with that name. If image is again not loaded successfully (because the file is

118

Architecture and Design Guide December 2008

not found), the AUI Technology software adds the .raw extension to the image name and attempts to load the file again. If the file is not successfully loaded, an error occurs. To summarize, the AUI Technology software tries to load images using the name specified in skin.xml in the following order: 1. From the ROM image 2. From the file system with the .png extension appended 3. From the file system with the.raw extension appended Java Wireless Client software includes a tool named ImageToRawTool that you can use to convert PNG images to raw platform-specific image formats. See the Tools Guide for more information about ImageToRawTool. By default, PNG and raw images used by the AUI Technology software are stored in the midp/src/highlevelui/lcdlf/lfjava/resource/skin directory. During the build, they are copied into the output/lib directory and are loaded from there at run time. You can choose a different directory path in which to store the images by specifying it as the value of the SUBSYSTEM_LCDLF_SKIN_RESOURCES_DIR makefile variable from the command line.

Note The directory path must be specified as an absolute path name.

Storing Image Resources in the ROM


For SkinRomizationTool to ROMize an image during the build, the PNG image (with .png extension) must be present in the midp/src/highlevelui/lcdlf/lfjava/resource/skin directory. Image ROMization is controlled by the Romize attribute in skin.xml. If an images Romize attribute is set to false, then the image is not ROMized during the build and will be loaded at run time from the file system. If the images Romize attribute is set to true is not ROMized during the build and is loaded at run time from the ROM image. See the Skin Authors Guide to Adaptive User Interface Technology for more information about SkinRomizationTool. As part of the build, SkinRomizationTool loads the PNG images, converts them into raw format (conversion is done in memory, so no .raw file is generated to the file system), and then generates the lfj_image_rom.c file into the output/generated directory that contains the ROMized image data. Later in the build process lfj_image_rom.c is compiled with other source files.

Chapter 11

Implementing the High-Level UI Using Adaptive User Interface Technology

119

RAW Format Platform Specification


Because platform graphic toolkits represent RAW image data differently, the SkinRomizationTool must know into which format it must convert images. Specify the RAW format in the file rawimage.xml located in the same directory as skin.xml. The file contains a single element named rawimage that has the following three attributes: Format, Colors, and Endian.

Format Attribute
The value of the Format attribute specifies how the alpha, red, green, and blue components of each pixel are represented. The currently supported values are ARGB and Putpixel. In the ARGB representation, the pixel color components are arranged in the following order: Alpha, Red, Green, Blue. The ARGB representation is used in the linux_qte port because it is the format used by the Qt graphic library. The Putpixel representation corresponds to the pixel representation used in the Java Wireless Client software PutPixel graphic library. It is used in the linux_fb and win32 ports.

Colors Attribute
The value of the Colors attribute specifies the number of bits used to represent the red, green and blue components (the alpha component is always an 8-bit value). The Java Wireless Client software supports the values 888 and 565. The value 565 specifies that each pixel representation allocate five bits for red, six bits for green, and five bits for blue. The 888 value specifies that each pixel representation allocate eight bits for red, eight bits for green, and eight bits for blue.

Endian Attribute
The value of the Endian attribute specifies which endian format the target platform uses. The possible values are Little and Big, where Little specifies that words start with the least significant byte, and Big specifies that words start with the most significant byte.

120

Architecture and Design Guide December 2008

This release of Java Wireless Client software does not support all combinations of attribute values. The following combinations are supported in this release of Java Wireless Client software.

ARGB, 888, Little ARGB, 888, Big Putpixel, 565, Little Putpixel, 565, Big

Because the RAW format is platform dependent, not all RAW variations are supported. If your platform does not use one of the supported combinations, you must add this support by modifying the following file:
midp/src/tool/imageutil/classes/com/sun/midp/imageutil/ ImageToRawConverter.java

Support for Virtual Keyboard


The virtual keyboard allows the porting engineer leeway in defining the look and layout of this feature. The graphical elements of the virtual keyboard are defined by the keyboard_skin.xml file. For more information on the keyboard_skin.xml file, see the Skin Authors Guide to Adaptive User Interface Technology. The virtual keyboard feature is implemented by setting a variable at build time. For more information on building the virtual keyboard, see the Build Guide. A porting engineer can change many elements of the virtual keyboard. This is done using the Keyboard class and making modifications to the Keyboard.java file.

Porting Steps
The following high-level steps describe the process typically used for porting AUI Technology software. For more information, and for the specific procedural steps used to port the Java Wireless Client software using the JavaCall porting layer, see the Sun Java Wireless Client Software Porting Guide. 1. Define the screen sizes in the constants.xml file in the configuration, as well as any other AUI Technology software specific constants. All of the following AUI Technology software constants begin with the CHAM_ prefix.

Chapter 11

Implementing the High-Level UI Using Adaptive User Interface Technology

121

CHAM_USE_IMAGES (boolean) When false, AUI Technology software does not attempt to load and use image resources. This is useful for early ports when image support in low-level graphics might not be implemented yet.

CHAM_ROMIZED_IMAGES (boolean) When false, AUI Technology software does not attempt to load image resources from the ROM image and only attempts to load the resources from the file system. Set this value to true if you ROMized some or all of AUI Technology softwares image resources.

CHAM_WIDTH (int) The width, in pixels, allotted on the display for AUI Technology software to display its screen contents.

CHAM_HEIGHT (int) The height, in pixels, allotted on the display for AUI Technology software to display its screen contents.

CHAM_FULLHEIGHT (int) The height, in pixels, allotted on the display for AUI Technology software to display its screen contents when in fullscreen mode. This might or might not be greater than the CHAM_HEIGHT value. For example, the device might give more pixels to AUI Technology software to show more of a game screen.

2. Port system events. Prior to porting AUI Technology software, it is important to have a working event processing service. Key press events must work correctly to test the AUI Technology software. For information about porting the event processing service, see Chapter 13 in this guide, and the Sun Java Wireless Client Software Porting Guide. 3. Port low-level graphics. AUI Technology software relies on a functional low-level graphics implementation. This means that the primitive drawing functions - for example, drawLine(), drawRect(), and fillRect() in Graphics.java - must be functional. It is possible to run the system without Image.java and the drawImage() functions being implemented during a ports initial stages. AUI Technology software resorts to solid fill colors when images are either not available or not implemented. You can use this characteristic to get visual feedback about how the system is running prior to implementing image support.

122

Architecture and Design Guide December 2008

4. Port the predictive input library. By using predictive text input, users can enter words often with a single key press for each character. For example, to enter the word how, user can press the 4, 6 and 9 keys, eliminating the need for the extra key presses (4, 4, 6, 6, 6, 9) required in standard text entry mode. Predictive text is an input mode similar to the following other modes:

Uppercase text entry Lowercase text entry Numerical text entry Foreign language text entry Use of the predictive text input mechanism is not mandatory for Java Technology for the Wireless Industry compliance. The predictive text API assumes that the handset device already has dictionary functionality, and the API is used to expose the dictionaries for use by the Java platform.

5. Review the Skin Authors Guide to Adaptive User Interface Technology and choose appropriate property and image values for the platform. The AUI Technology software release includes default values and images that you can use early in the porting process. After you have the software working, change the property and image values to apply the devices native look and feel to Java platform applications.

Note Be sure to change the images in the


midp/src/highlevelui/lcdlf/lfjava/resource directory and not in the output/lib directory. Images are copied to output/lib during the build and images in that directory are overwritten.

Note If you ROMize all image resources on your platform, remove them from the
midp/src/highlevelui/common/resource directory so they are not unnecessarily duplicated in the file system when you deploy your bundle. 6. Build Java Wireless Client software. Once you are able to build AUI Technology software and it works properly, you can decide whether or not to tune the ports image components. For example, all images can be ROMized if file system support is not yet functional. Also, you might initially use a compressed format and then later switch to an uncompressed format to improve performance. See the Sun Java Wireless Client Software Build Guide for more information about building Java Wireless Client software.

Chapter 11

Implementing the High-Level UI Using Adaptive User Interface Technology

123

124

Architecture and Design Guide December 2008

12

Implementing the High-Level UI Using Platform Components


This chapter describes how to port the high-level user interface using the native platforms GUI components to provide a unified user interface library. The method of porting described in this chapter requires much more time and effort than using AUI Technology software as described in Chapter 11. Only use this method if AUI Technology software is not appropriate for your platform. This chapter is intended to be used as an adjunct to the API documentation shipped with Java Wireless Client software.

Overview
The MIDP specification requires that a specific set of high-level GUI components be available for constructing the graphical user interface. Java Wireless Client software provides services that help in the construction of these MIDP components. Java Wireless Client software constructs the full complement of MIDP components from a simpler set of platform components specified in the Java Wireless Client software highlevel UI porting interface specification. The platform components are constructed from basic components provided by the platformss native operating system library. You are responsible for creating a platform component adapter for each platform component required by the Java Wireless Client software high-level UI porting interface specification. The Java Wireless Client software constructs the MIDP components using the platform component adapters. Because you write the platform component adapters directly on your platform, you do not have to take the time to understand the internal functionality of the Java Wireless Client software.
FIGURE 12-1 shows the major elements of the high-level UI in a Java Wireless Client software port.

Chapter 12

Implementing the High-Level UI Using Platform Components

125

FIGURE 12-1

Major Elements of the High-Level UI in a Java Wireless Client Software Port


Displayable (Java platform code)

Java Wireless Client software

Displayable look and feel implementation (Java platform code) Displayable native peer (C code)

Porting interface Platform component adapter Native platform (Native code) OS component library

The porting interfaces are defined by a set of header files. The following two sets of functions are defined:

Porting functions that you must implement based on the OS component library. These are called platform component adapters. Callback functions provided by Java Wireless Client software for communicating with the Java platform. For example, user input can be converted to Java events by calling midpStoreEvent().

See the Native API reference for the list of header files that define the porting API.

Component Dependencies
Many components depend on other components. For example, a List component is constructed from the ChoiceGroup and Form components. This means that you need to adopt a strategic approach to the porting process by creating constituent parts in the right order to create more complex components. Also consider the requirements that other crucial parts of the system have for various GUI components. For example, the low-level graphics and images services and the AMS both require the Canvas component. Therefore, before you can completely port and test the AMS, you must implement the Canvas component. In many cases, a components functionality need not be fully implemented to satisfy the dependency.

126

Architecture and Design Guide December 2008

FIGURE 12-2 shows the high-level GUI components and the components on which they depend.
FIGURE 12-2

High-Level GUI Components and Dependencies


2
List

1
Canvas

3
TextBox

4
Alert

7
Date Field Choice Group Form Text Field Gauge

5
String Item

6
Image Item

8
Custom Item

Soft Button

Menu

Spacer (Porting not required)

Date Editor

Item

Label Highlight (focus) Focus User input

Porting Steps
Following are some strategic guidelines you can use during your port:

Be sure that the event system and the low-level graphics system are ported and working before you port the high-level GUI components. Implement the components iteratively.

Chapter 12

Implementing the High-Level UI Using Platform Components

127

Constituent components need not always be ported completely. Implement as much functionality as required to implement higher-level components. After you implement higher-level components, return to finish the lower level components. This makes components available so that the porting of multiple components can proceed in parallel.

The following high-level steps describe the order in which a typical port might proceed. The steps correspond to the numbers shown in FIGURE 12-2. 1. Implement the Canvas component. The Canvas component is used to paint low-level graphics on the screen. The low-level graphics and images service and the AMS depend on the Canvas component. The Canvas component depends on the SoftButton component because it must be able to map abstract commands to soft buttons. The Canvas component also depends on the Menu component because when an application uses a large number of abstract commands they are contained in a menu. 2. Implement the List component. List is the most commonly used component and is used by the AMS. The constituent components (ChoiceGroup and Form) do not have to be completely implemented to support the List component. For example, the List component only requires single-item selection, so you can implement multiple-item selection in the Form component later. The following steps describe the order in which a typical port may proceed. a. Implement the Item component. The ChoiceGroup components requires basic Item component functionality. If it has not already been implemented you must implement the Item component now. b. Implement the ChoiceGroup component. The List component is implemented as a Form with a single ChoiceGroup. c. Implement the Form component. The Form component is the container for the ChoiceGroup component. While implementing the Form component, be sure to implement the required Item component functionality. 3. Implement the TextBox component. The TextBox component is used to enter URLs during over-the-air (OTA) installation. The TextBox component only requires single-item selection, so you can implement multiple-item selection in the Form component later. The following steps describe the order in which a typical port can proceed.

128

Architecture and Design Guide December 2008

a. Implement the Item component. If you have not already implemented the Item component, implement it now. b. Implement the TextField component. The TextBox component is implemented as a form with a single text field. c. Implement the Form component. If you have not already implemented the Form component, implement it now. 4. Implement the Alert component. Alerts are required by the AMS and the runtime security service. The following steps describe the order in which a typical port may proceed. a. Implement the Alert component with text content only. Start by supporting simple text content. b. Add support for image content. Add the ability for the Alert to contain images. c. Add support for the Gauge component. Because the Gauge component depends on it, if you have not already implemented the Item component, implement it now. 5. Implement the StringItem component. StringItem components are commonly used to construct complex Forms and are usually used for descriptive purposes. Keep the following in mind while implementing the StringItem component:

StringItem components must be flexible. You must be able to lay them out continuously to fill the width of the screen. The StringItem component must be able to accommodate different font sizes. The StringItem component must be displayable as both a button and as flat text. If your platform supports the display of flat buttons, you can unify the implementation of the StringItem and Button components.

6. Implement the ImageItem component. Implementing the ImageItem component is similar to the StringItem component. One significant difference is that there are far fewer sizing constraints because the dimensions of images are known. If your platform supports the display of an image in a Button, you can unify the implementation of the StringItem and button components.

Chapter 12

Implementing the High-Level UI Using Platform Components

129

7. Implement the DateField component. The DateField component is used to display and set dates and times. The following steps describe the order in which a typical port can proceed. a. Implement functionality to display a specified date and time. b. Implement the DateEditor component. The DateEditor component provides users with the means to change dates and times. 8. Implement the CustomItem component. The CustomItem component provides a paintable Item component inside a Form. The following steps describe the order in which a typical port can proceed. a. Implement the off-screen buffer. b. Implement capture functionality. The CustomItem component must be able to capture user input events and deliver them to the Java platform. Java Wireless Client software provides callback functions to deliver these events. c. Visibility tracking and notification. The CustomItem component must notify the Java platform when it becomes visible or invisible because it is scrolled on or off the screen.

Testing
It is best to test your port as it progresses. Write your tests as MIDlets that test specific component functionality, rather than a broad spectrum of components and functionality. The MIDP Reference Implementation includes MIDlets that exercise high-level UI functionality and can be used for testing. See the documentation included with the MIDP Reference Implementation for details. If your device supports command-line input from a terminal, port the runMidlet utility so that you can run MIDlet tests without full AMS functionality.1 The runMidlet utility allows you to run an arbitrary MIDlet class directly from the command line. The following example shows the syntax for the runMidlet utility.
CODE EXAMPLE 12-1

runMidlet Utility Syntax

runMidlet -classpathext midlet.jar internal class_name

1. Java Wireless Client software includes versions of runMidlet that work on the Linux operating system and the Microsoft Windows operating system.

130

Architecture and Design Guide December 2008

If your device does not support terminal input, your platforms AMS can call midpRunMidletWithArgsCP() to run MIDlet tests. See the midp.h API reference documentation for details. After your port is fully functional and stable, you can use the Java Technology for the Wireless Industry TCK and any other available test suites to further test the high-level UI.

Chapter 12

Implementing the High-Level UI Using Platform Components

131

132

Architecture and Design Guide December 2008

13

Porting the Event Processing Service


The event processing service enables a devices native code to convert native events to a format that the Java platform event (Java event) system can understand. Ideally, an event is delivered to a Java platform object (Java object) by calling a method on it, however, this is not possible because the event originates from native code, and because CLDC HotSpot Implementation has no facility that enables native code to call methods on Java objects. Instead, the native code places the native event into an event queue. A Java thread calls into native code to retrieve the event from the event queue. This chapter describes the native interfaces to the event queue. This chapter also describes flow-of-control issues that determine when native code can place events into the queue and when Java threads can remove events from the queue. MIDP must be able to receive events from outside the Java platform. The way that MIDP receives events depends, in part, on how the VM is invoked. See Section 10.4 Invoking the Virtual Machine in the CLDC HotSpot Implementation Porting Guide for information about invoking the VM. The central issue regarding event delivery is control flow, which is highlighted by the following questions:

How many native threads are running? Which thread receives events? Which thread runs the VM? Does the system call MIDP to deliver events or MIDP query the system for events?

The event processing service collects events from the native system in an event queue. These native events are converted into Java events, merged with a stream of events that originates from the Java layer, and are placed into a unified event queue. Events are processed one at a time. The processing of one event is always completed before the processing of the next event begins. This satisfies the event serialization

Chapter 13

Porting the Event Processing Service

133

requirements of the MIDP LCDUI package. Serial event processing is also useful for managing multi-threaded control flow that occurs in various portions of the implementation. Multiple Java threads handle control flow by posting events. The event stream from the native event queue and event stream from the Java platform are interleaved into a unified Java event queue. The unified event queue is processed by a single Java thread. Other subsystems that block threads, such as networking, multimedia, and WMA, cooperate with this service in conserving battery power when the VM is idle. Have the subsystems register for an event instead of waiting until some external state changes. This allows the VM to go to sleep waiting for the event, reducing CPU usage and thus conserving battery power.

Event System
FIGURE 13-1 shows an overview of what happens when Java Wireless Client software processes an event.

134

Architecture and Design Guide December 2008

FIGURE 13-1

Event Queue Components and Interactions Event listeners


6

Event dispatch thread

Java events (repaint)

Java event queue

Native events
4

Native event monitor (Java thread)


1 3

Native event queue

Native events

The following steps describe the numbers shown in FIGURE 13-1: 1. The native event monitor (NEM) thread waits for a native event. The NEM thread is a Java thread that monitors the arrival of native events. 2. The native system submits an event. This is where your porting effort is focused and is described in more detail in Submitting Native Events on page 136 below. 3. The NEM thread wakes up. 4. The NEM thread converts the native event to a Java object and places the event in the Java event queue. 5. The event dispatch thread processes the Java event. The event dispatch thread pulls the next event from the event queue and chooses an event listener based on the type of event. 6. The event dispatch thread calls the appropriate event listener for the dispatched event.

Chapter 13

Porting the Event Processing Service

135

Submitting Native Events


The preceding section describes the entire event processing service. You are responsible for implementing Step 2 (submitting native events). The following steps describe the step-by-step functionality that your code must provide: 1. Declare a midpEvent data structure. 2. Use the MIDP_EVENT_INITIALIZE macro to initialize the midpEvent data structure. 3. Complete the fields of the midpEvent data structure. This is described in more detail in Complete the Event Fields on page 136. 4. Call the StoreMIDPEventInVmThread function to store the event in the event queue and to wake up the NEM thread. The native event queue must be thread safe if multiple native threads have access to it. To ensure that multiple access does not corrupt the queue, a locking system is required. This is described in more detail in Locking on page 137. 5. Wait for the next native event. How you wait is determined by your platform.

Note The data structures and functions that you need to call are described in the
Native API Reference. Refer to the section that describes midpEvents.h.

Complete the Event Fields


The MidpEvent data structure is a C struct with several integer and string fields. There are enough fields of each type to accommodate events that can occur in most systems. Platform-specific event code transforms information received from the platform by setting particular fields of the MidpEvent data structure. The type field of the event must always be set. For the other required fields, the meaning of the data depend upon the particular event type. For example, the code sample shown in CODE EXAMPLE 13-1 shows a pen event being submitted into the native event queue.
CODE EXAMPLE 13-1

Code Completing a MidpEvent Data Structure

void handlePointerEvent(...) { MidpEvent event; MIDP_EVENT_INITIALIZE(event); event.type = MIDP_PEN_EVENT; [defined in midpEvents.h]

136

Architecture and Design Guide December 2008

CODE EXAMPLE 13-1

Code Completing a MidpEvent Data Structure

event.intParam1 = PRESSED; [or DRAGGED or RELEASED] event.intParam2 = the x position of the event ; event.intParam3 = the y position of the event ; StoreMIDPEventInVmThread(evt, 0); }

Locking
Operations on the native event queue can occur on multiple threads, so you must create a facility that protects the event queue from concurrent access. This is accomplished through an event queue locking API defined in the midpServices.h header file. This API defines create, lock, unlock, and destroy operations. The functions defined by this API are called by the event queue code in MIDP and must be implemented by the platform-specific code. The locking functions are described in the Native API Reference. Refer to the section that describes midpServices.h, located in the Misc. System Services category. You must implement the following functions:

midp_createEventQueueLock midp_waitAndLockEventQueue midp_unlockEventQueue midp_destroyEventQueueLock

The semantics of these APIs are very similar to their equivalent POSIX threads (pthreads), and these functions can be implemented using the corresponding pthread functions:

pthread_mutex_init pthread_mutex_lock pthread_mutex_unlock pthread_mutex_destroy

Circumstances exist in which a single thread is responsible for both submitting events into the event queue and removing them. The VM is the only part of the system that removes events from the event queue. If the thread that runs the VM is also the only thread that submits events into the event queue, it is not possible to have concurrent access to the event queue. Even in this case, the locking functions are still called and you must provide implementations of the locking functions, but they can be empty.

Chapter 13

Porting the Event Processing Service

137

Note It is important to understand that it is only possible to guard against


concurrent access to the event queue if all of the events are submitted from the same thread. Certain parts of the platform, such as networking or multimedia, might generate events from another thread. If any possibility exists that even a single event might be generated from some other thread, then the locking functions must be implemented to guard against concurrent access.

Setting the MAX_EVENTS Constant


The MAX_EVENTS constant limits the maximum number of events that can be placed in the native event queue at one time. You can change the value of MAX_EVENTS to work with the speed and memory requirements of your device. See Chapter 4 for the location of the MAX_EVENTS constant and instructions on modifying a constants value. Under most circumstances, events come in at a moderate rate and are processed quickly by the VM. However, if events occur at a high rate, and if the VM is not run frequently enough or if its time slice is not long enough, events can start to build up in the native event queue. In most cases, the cluster of events lasts briefly. For example, if the user drags the pointer across the screen very quickly. The VM eventually catches up and drains the events from the queue. Set the value of MAX_EVENTS to accommodate the largest expected flurry of events.

Types of Event Systems


This section discusses the flow of control between the VM and the rest of the native system, and how it interacts with event processing. Please refer to Chapter 10 of the CLDC HotSpot Implementation Porting Guide, Implementing J2ME Profiles, for information on the different modes in which the VM can be invoked, the APIs used for processing events, and code samples that illustrate use of these APIs.

Normal Mode
In normal mode, the main processing loop resides within the VM.

Note Normal mode is often referred to as master mode because it is


complementary to slave mode described later.

138

Architecture and Design Guide December 2008

The general flow of control in normal mode is as follows: 1. Platform-specific code initializes. 2. Platform-specific code calls JVM_Start(), which does not return until the VM exits. 3. The VM main loop time slices between Java threads and periodically calls JVMSPI_CheckEvents(). 4. JVM_Start() returns when all Java threads exit or when VM termination is requested. This flow of control is illustrated in FIGURE 13-2.
FIGURE 13-2

CLDC HotSpot Implementation Running in Normal Mode


CLDC VM Java thread 1 Java thread 2 Native event code

Initialization

JVM_Start()

JVMSPI_CheckEvents(...)

to check the status of pending I/O events, * Uses select() or poll()events. Unblocks threads as necessary. user interface events, and other

Chapter 13

Porting the Event Processing Service

139

JVMSPI_CheckEvents() has several responsibilities. It must check for the occurrence of any event that can possibly occur in the system. Some events, such as user interface events, must be submitted into the event queue as described in Event System on page 134. Other events, such as network traffic, are destined for a particular Java thread. The CheckEvents code must awaken the appropriate thread so that the network traffic can be processed. Finally, if no events are available, the code must sleep for as long as the VM requests (possibly indefinitely). For normal mode operation, MIDP provides a platform-independent implementation of JVMSPI_CheckEvents(). In turn, this implementation relies on platform-specific code to gather event information for it. This platform-specific code resides in the checkForSystemSignal() function that you must implement as part of your porting effort. Its responsibilities are similar to those of JVMSPI_CheckEvents() but its parameters and return values are different. It must convert the event into a MidpEvent structure as previously described. In addition, it must return information such as a file descriptor to the platform-independent layer so that any Java threads waiting for this event are awakened. This information is returned in a MidpReentryData structure. The checkForSystemSignal() function and the data structures it uses are described in the midp_checkSysSignals.h header file.

Slave Mode
In slave mode, the main processing loop resides outside the VM. The general flow of control in slave mode looks like this: 1. Platform-specific code initializes. 2. Platform-specific code calls JVM_Start(), which returns immediately. 3. Platform-specific code runs a main loop that calls JVM_TimeSlice() to run Java threads for one time slice and checks for any events that occurred in the system, awakening Java threads as necessary. 4. The VM terminates when all Java threads exit, or when VM termination is requested. 5. The platform-specific main loop exits. The control flow in slave mode is inverted in relation to normal mode. In normal mode, the VM time-slices Java threads and calls platform-specific code periodically to check for events. In contrast, in slave mode, the platform-specific code calls the VM periodically and checks for events in between calls to the VM. The eventchecking step for slave mode (Step 3) has the same responsibilities that JVMSPI_CheckEvents() has for normal mode.

140

Architecture and Design Guide December 2008

Slave mode is necessary in cases where the main processing loop cannot reside in the VM. An example of this occurs with user interface toolkits such as Qt. In a Qt environment, the main loop resides within the member function QPEApplication::enter_loop(). This function calls Qt callbacks to deliver events, and it blocks until an event is available. JVM_TimeSlice() must be called repeatedly for Java threads to make progress. In a Qt-based system, this can be accomplished by ensuring that an event is always available for processing. Events are generated by setting up a timer event for a short time (or zero time) in the future. When the the timer event fires, the Qt calls the appropriate callback, which calls JVM_TimeSlice() and then reschedules a timer event. Handling of events, (for example, for the user interface and the network) are handled through other Qt callbacks. This flow of control is illustrated in FIGURE 13-3.
FIGURE 13-3

CLDC HotSpot Implementation Running in Slave Mode


Qt main loop Qt object Qtimer vm_slicer VM Java thread 1 Java thread 2

Initialization

JVM_SetConfig(SLAVE_MODE) JVM_Start() QPEApplication:: enter_loop()

JVM_TimeSlice(...)

JVM_TimeSlice(...)

* User interface events and pending I/O are handled through Qt events. Slot
handling code is used to unblock threads.

Chapter 13

Porting the Event Processing Service

141

Choosing Normal or Slave Mode


The preceding sections illustrate some of the issues to consider when choosing between normal and slave modes. If your system has a call that reads events from an event queue, it might make sense to run the VM in normal mode. Place a call to the function that reads events in the implementation of the checkForSystemSignal() function. If your system controls the main loop and issues callbacks to deliver events, it might make sense to run the VM in slave mode. Write callbacks to submit events into the MIDP event queue. In addition, you must employ a technique (such as a timer event) to ensure that JVM_TimeSlice() is called repeatedly. For example, in a non-JavaCall implementation, midp_slavemode_schedule_vm_timeslice() can be used to request the VM to schedule a time slice to be executed as soon as possible. The midp_slavemode_time_slice() method can then be called to execute bytecodes for that time slice. On a JavaCall platform, the javacall_schedule_vm_timeslice() can be used to invoke platform-specific code, such as a timer setup, with the time slice then executed by means of javanotify_vm_timeslice(). Both of these approaches - making system calls into the event queue or using callbacks to deliver events - run the entire system in a single native thread. If the system can support multiple native threads, it might be possible to run the VM in normal mode in its own native thread. This technique adds complexity because the coupling between the systems event processing and the submission of events to the VM using checkForSystemSignal() must be done in a thread-safe manner. However, running the VM in normal mode can provide increased throughput and responsiveness if the OS can switch threads more quickly than time slices can be scheduled in the slave mode technique.

Note To implement slave mode in your system, you must build the JavaCall and
MIDP components using the SUBSYSTEM_EVENTS_MODULES=slave_mode flag. For more information, see the Build Guide.

142

Architecture and Design Guide December 2008

Chapter 13

Porting the Event Processing Service

143

144

Architecture and Design Guide December 2008

14

Application Management with the Java Platform


This chapter discusses how to port and customize the Application Management Service (AMS) subsystem. Users interact with the AMS via the graphical user interface (GUI) on their handset or device. The AMS also manages scheduling and other low-level operations between applications and the virtual machine. The AMS is responsible for the following services:

Installing MIDlet suites Updating MIDlet suites Removing MIDlet suites Displaying information about MIDlet suites Invoking MIDlet suites Managing communication between installed MIDlets Dynamically downloading MIDlet suites Updating MIDlet settings

This section describes the AMS and its interactions with other parts of the Java Wireless Client software.

Note Although it is related to the AMS, because of its complexity, the push
subsystem is described in its own chapter (Chapter 15).

Chapter 14

Application Management with the Java Platform

145

Native AMS
You have two choices for integrating Java Wireless Client software with AMS functionality: Java AMS or the native AMS. Java Wireless Client software provides a Java programming language implementation of the AMS (referred to as the Java AMS). The bulk of this chapter covers the Java AMS. The alternative to the Java AMS is to integrate Java Wireless Client software with an external AMS implemented in native code. This is called the native AMS or NAMS. Java Wireless Client software does not provide a NAMS implementation, but instead provides a native API (NAMS API) through which the external NAMS implementation communicates with Java Wireless Client software. This API allows an external implementation to initiate Java application state changes and to receive notification when state changes occur. The NAMS API is fully documented in the Native API Reference in the Native AMS section, in particular in the file midpNativeAppManager.h. The top-level URL to this area of the documentation is:
doxygen/html/group__nams.html

Note The NAMS API is not thread safe. Therefore, any calls to the NAMS API
must be on the same native thread that runs the Java virtual machine.

AMS Functionality
AMS is a catch-all term used to describe the functionality on a device that installs, lists, runs, and removes applications. The AMS is a group of components that can be modified or replaced individually. For MIDlet suites, the AMS must provide all of the application management functionality required by the MIDP 2.1 Specification as shown in TABLE 14-1.

146

Architecture and Design Guide December 2008

TABLE 14-1

Application Management Functionality


Description

Application Management Functionality

Application Manager Uninstaller

Interacts with users to manage applications currently installed on the device. Interacts with users to uninstall applications. Sometimes this functionality is part of the Application Manager. Enables users to discover new applications to install over the air and automatically invokes the graphical installer when they decide to download one. The discovery application might be the existing web browser on the device. Interacts with users to install an application over the air. Stores applications and their data across multiple uses of the device. Runs installed MIDlets. This is the devices Java runtime environment and Java Wireless Client software extends it to run system applications written as MIDlets, such as the discovery application and graphical installer.

Discovery application

Graphical installer Persistent application storage (suite storage) MIDP runtime environment

Test and development devices might have the additional functionality shown in TABLE 14-2.
TABLE 14-2

Additional Test and Development Functionality


Description

Additional Functionality

Autotester

An application that the TCK testing framework uses to install and run sequences of tests without user intervention. A command-line application that runs an installed MIDlet. It serves as an example of how to use the run function of the Java Wireless Client software C API.

Command-line MIDlet runner

Chapter 14

Application Management with the Java Platform

147

TABLE 14-2

Additional Test and Development Functionality


Description

Additional Functionality

Command-line MIDlet suite lister

A command-line application that lists MIDlet suites. It serves as an example of how to use the listing functions of the Java Wireless Client software C API. A command-line application that removes MIDlet suites. It can serve as an example of how to use the removal function of the Java Wireless Client software C API. A command-line application that adds and removes MIDP software CAs to and from the trusted keystore used by the Java Wireless Client software installer MIDlets.

Command-line MIDlet suite remover

Public keystore manager

FIGURE 14-1 shows the interactions of some of the components described in TABLE 14-1 and TABLE 14-2.
FIGURE 14-1

AMS Architecture on a Device


Invoke Application Manager Invoke

Discovery Application

Invoke Autotester Run test MIDlet Graphical Installer

Run MIDlet suite

Uninstaller

MIDP Runtime Environment Retrieve MIDlet Remove suite Get and set MIDlet suite information

Store MIDlet suite

Store and remove MIDlet suite

Persistent Application Storage

148

Architecture and Design Guide December 2008

External Interactions With AMS


TABLE 14-3 shows how the AMS interacts with various Java Wireless Client software

systems.
TABLE 14-3 System

AMS Interaction With Java Wireless Client Software Systems


Description

Networking Graphical window system File system RMS

Uses HTTP and HTTPS. Uses the GUI for user interaction. Uses the following standard file system services: create, write bytes, read bytes, truncate, rename, and delete. Uses the following internal services: Gets the RMS space used by the given MIDlet suite. Gets the available space for a MIDlet suite. Removes a MIDlet suites record stores. Note: AMS system MIDlets use standard RMS services. Uses the following internal services: Gets a requested resource from the current MIDlet suites JAR file. Starts the virtual machine with the MIDletSuiteLoader class. Uses the following internal services: Registers static push connections. Removes all alarms and push connections for a MIDlet suite. Gets the default permissions for a suite. Uses the following services: SHA-1 secure hash function RSA public key decrypting X.509 certificate parsing and verification PKCS signature verification

Java virtual machine

Push

Permission management Cryptographic system

The AMS also provides the following functionality:


Authenticates and authorizes signed applications for Java platform installers Performs the following installation services for native and Java platform installers:

Parses and verifies JAD files

Chapter 14

Application Management with the Java Platform

149

Converts the JAD file and manifest files to Unicode from UTF-8 Extracts information from the JAD file Parses and verifies manifest files Extracts resources from JAR files Compares the values of the attributes in the JAR file manifest and JAD files Compares the versions of a MIDlet suite during suite updates

Performs MIDlet storage services for native installers, Java platform installers, and application managers, including the following functions:

Stores and updates a MIDlet suite Gets a MIDlet suites previous installation information Gets the size of a MIDlet suite, including RMS records and any other information stored for that suite Gets the application properties of a MIDlet suite Gets a MIDlet suites current permissions Gets the push interrupt settings of a MIDlet suite Removes a MIDlet suite Gets a list of all MIDlet suite identifiers Runs a MIDlet Optionally, preprocess images in the JAR file and creates a cache in persistent storage to improve MIDlet startup time

Manages communication between installed MIDlets, for example, passing data between one application and another Provides the MIDlet auto-invocation (push) subsystem with a service to start a MIDlet after the user grants permission Provides automated test functionality required for TCK testing

For a list of commands available for interacting with installed MIDlets, see the Sun Java Wireless Client Software Tools Guide.

MIDlet Suite Attributes


The AMS is used to install, run, manipulate, and remove MIDlets in the Sun Java Wireless Client. MIDlets can be run alone, but are generally installed and managed as part of a MIDlet suite. That is, a JAR file containing more than one MIDlet.

150

Architecture and Design Guide December 2008

Each MIDlet suite has a JAD file that contains a list of attributes that give information about the MIDlet suite, the MIDlets within it, and how the MIDlets should be handled. (This information is also contained in the manifest that goes with the JAR.) For example, the JAD property MIDlet-Launch-Background:yes tells the AMS to launch the MIDlet directly to the background.
CODE EXAMPLE 14-1 shows the basic descriptors that can be found in a MIDlet suites JAD file. These basic descriptors are largely self-explanatory.
CODE EXAMPLE 14-1

JAD file descriptors

MIDlet-1: starBurst, /SB_icon.png, starBurstMIDlet MIDlet-Icon: /SB_icon.png MIDlet-Jar-Size: 15450 MIDlet-Jar-URL: starBurst.jar MIDlet-Name: starBurst MIDlet-Vendor: Chocolate Technology, Inc. MIDlet-Version: 1.0 MicroEdition-Configuration: CLDC_HI-2.2 MicroEdition-Profile: MIDP-2.2

Extended MIDlet Attributes


The Sun Java Wireless Client software provides a set of extended MIDlet attributes that can be used to specify more advanced characteristics of an individual MIDlet. These advanced attributes are useful to the AMS, tell it exactly how the MIDlet should be handled.

Note Extended MIDlet attributes apply only to MIDlets within signed MIDlet
suites. If a suite is unsigned, the extended attributes for a MIDlet are ignored. For more information on signing MIDlet suites, see the Tools Guide. Extended MIDlet attributes can be defined in both a MIDlet suites manifest file and JAD file, or only in its manifest file. If defined in both places, the value of an extended attribute must match. If an extended attribute is defined only in the JAD file, it is ignored.
CODE EXAMPLE 14-2 shows the extended MIDlet attributes.

Chapter 14

Application Management with the Java Platform

151

CODE EXAMPLE 14-2

Extended MIDlet attributes

MIDlet-Heap-Size: 150k MIDlet-Background-Pause: yes MIDlet-Launch-Background: no MIDlet-Launch-Power-On: yes MIDlet-No-Exit: yes

The following provides more information about the extended MIDlet attributes.

MIDlet-Heap-Size. Defines the maximum heap available for the MIDlet. If the AMS explicitly defines the maximum heap size available and the size defined in the extended attribute is larger, the value of the extended attribute is ignored.

Note In the Sun Java Wireless Client software, the maximum heap size is 1 MB for
fixed policy and 4 MB for open policy. (Open policy is the default.)

MIDlet-Background-Pause. If the attribute value is yes, the pausedApp() method is called when the AMS moves the MIDlet to the background, and the MIDlet is moved to a paused state. MIDlet-Launch-Background. If the attribute value is yes, the MIDlet is launched directly to the background. Once a MIDlet is launched directly to the background, a user interacting with the AMS cannot move it to the foreground. MIDlet-Launch-Power-On. If the attribute value is yes, the MIDlet is launched every time the JVM is started. If multiple MIDlets have this designation and launch when the VM is started, the order of launch is not controlled. If a MIDlet is newly installed and the JVM is already running, the MIDlet is launched as soon as the installation process completes. MIDlet-No-Exit. If the attribute value is yes, the MIDlet is only allowed to exit when the AMS calls the destroyApp() method.

Inter-MIDlet Communication
The Java Wireless Client software allows MIDlets installed in the AMS to share information with other MIDlets, even if those MIDlets are not installed as part of the same MIDlet suite. This information sharing between MIDlets is made possible by the Pipe Communication Protocol (PCP), part of the Java platforms Generic Connection Framework (GCF).

152

Architecture and Design Guide December 2008

Note Information sharing between MIDlets is only possible within a single virtual
machine instance, running in multithread (MVM) mode. The ability of MIDlets to share information with other MIDlets provides many possible enhancements for end user applications on a device. For example, the user has a handset with an email application that came installed from the vendor and an address book application she later downloaded herself. She opens the email application and types in an address to send a message. The email MIDlet opens a connection to the address book MIDlet and sends the typed-in address, asking if there is a name associated with it in the address book. If the answer is yes the address book MIDlet returns the name and closes the connection. The name then shows up in the address line instead of the address the user typed in. If the answer is no, the connection is kept open and when the message is sent, the email MIDlet hands the address off to the address book MIDlet. The next time the user opens her address book, the application asks her if she wants to provide a name to go with the address it received from the email MIDlet. Although neither MIDlet was installed into the device as part of the same MIDlet suite, the PCP mechanism has allowed both applications to communicate inside the AMS.

Using the Pipe Communication Protocol


The Pipe Communication Protocol (PCP) is a platform-independent protocol that makes use of the Link and Service APIs to structure and fulfill communication requests. Therefore, this is no need to port this protocol. A connection between two MIDlets is made using a connection request mechanism similar to a server socket connection request. But, instead of using a port number to define the connection, the connection is defined using a MIDlet name and version number. The MIDlet name and version number is provided to a requesting MIDlet by a MIDlet connection server, which is part of the AMS functionality. The name and version number is provided to the MIDlet connection server by a server-side MIDlet when a connection is opened.

Note The MIDlets opened pipe connection is considered a server-side


connection, with the MIDlet connecting to it acting as the client. The GCF connection string used in this mechanism takes the following format:
Chapter 14 Application Management with the Java Platform 153

To open a server-side connection pipe://:pipe_server_name:pipe_version; To open a client connection pipe://*:pipe_name:pipe_version;

When a MIDlet starts up inside the AMS, it opens a pipe connection and waits for another MIDlet to connect to it, as shown in CODE EXAMPLE 14-3.
CODE EXAMPLE 14-3

MIDlet server-side connection

PipeServerConnection serverConn= (PipeServerConnection) \ Connector.open(pipe://:TestPipeConnection:1.0;); PipeConnection dataConn = (PipeConnection) \ serverConn.acceptandOpen();

Once a MIDlet opens a server-side connection, a client MIDlet can connect to it, as shown in CODE EXAMPLE 14-4.
CODE EXAMPLE 14-4

Client MIDlet connects to server-side MIDlet

PipeConnection dataConn= (PipeConnection) \ Connector.open(pipe://*:TestPipeConnection:1.0;);

Once a server-client connection is made between two MIDlets, both open communication streams and transfer data, as shown in CODE EXAMPLE 14-5.
CODE EXAMPLE 14-5

Transferring data between server-side and client MIDlets

DataInputStream in = dataConn.openDataInputStream(); DataOutputStream out = dataConn.openDataOutputStream(); out.writeUTF(text);

Once the requested data is transferred between the server-side and client MIDlets, the connection is torn down using appropriate close methods, as shown in CODE EXAMPLE 14-6.
CODE EXAMPLE 14-6

Closing the connection between MIDlets

out.close(); in.close(); dataConn.close();

154

Architecture and Design Guide December 2008

Once a server-side MIDlet closes a connection to a client MIDlet, another server-side connection can be opened, to wait for another client connection, as shown previously in CODE EXAMPLE 14-3.

Note Best practice is to create a new thread for each incoming client.

Downloading Dynamic Components


The Java Wireless Client software provides the ability to download and install dynamic components in the AMS. Dynamic components are sets of functionality (in the form of JAR files) that can be loaded into the AMS and shared by all MIDlets and MIDlet suites installed on a device. For example, a dynamic component could be functionality provided by a specific Java Specification Request (JSR). Once downloaded and installed, the files, classes, and functionality contained in the components JAR can be accessed by any MIDlet suite running in the AMS, as though the dynamic components were part of its own suite.

Note This sharing of dynamic functionality is possible only when initiated by an


Over the Air (OTA) request from the Component Manager. For more information on the Component Manager, see Configuring the AMS for Dynamic Components on page 156. The Java Wireless Client software is configured by default not to allow downloading and installation of dynamic components into the AMS. Therefore, to make this functionality available, special steps must be taken. These steps are described in Configuring the AMS for Dynamic Components on page 156. Dynamic components have the potential for mischief, so some security restrictions are imposed upon their usage. For more information, see Security Restrictions on page 158.

Configuring the AMS for Dynamic Components


To configure the Java Wireless Client software to allow downloading and installation of dynamic components, you must set the following build flag during the system build process: USE_DYNAMIC_COMPONENTS=true
Chapter 14 Application Management with the Java Platform 155

Setting this flag to true when building the Java Wireless Client does the following three things: 1. The com.sun.midp.amsservices.AMSServices and com.sun.midp.amsservices.ComponentInfo interfaces are compiled into the system and become available to user applications (MIDlets). 2. Creates a Component Manager MIDlet that can be used to download specific dynamic content over the air from an URL. 3. Puts the Component Manager MIDlet into the Java Wireless Client software GUI in the Java AMS menu, just after the Installer and Certificate Manager MIDlets. If USE_DYNAMIC_COMPONENTS=false is set, no dynamic component capabilities are available in the Java Wireless Client software. (This is the default setting.)

Defining the Location for Dynamic Content


The current implementation of dynamic component capabilities in the Java Wireless Client software does not allow just any content to be downloaded from just any location. Rather, the location from which dynamic content can be downloaded must be specified at build time in the following file: midp_dir/src/configuration/configuration_xml/share/ suitestore_constants.xml The administrator building the Java Wireless Client software (for example, a handset manufacturer) sets the download location in the suitestore_constants.xml file by defining the AMS_CMGR_DEFAULT_COMPONENT_URL constant to some HTTP URL. Once the download location is specified and the build is launched, the ability to download dynamic content is built in to the Java Wireless Client software. When the end user of the device pulls up the Component Manager option through the AMS GUI menu item, the location listing for downloading dynamic content will be the one specified during the build process.

Note The location defined in the suitestore_constants.xml file can be modified by


a text field in the Component Manager MIDlet. For security purposes, it is recommended that you remove this field during he porting process. To do this, edit the makeInstallDialog() method in the file midp_dir/src/ams/dynamic_component_manager/reference/classes/com/ sun/midp/appmanager/ComponentManager.java. For more information on building the Java Wireless Client software, see the Build Guide.

156

Architecture and Design Guide December 2008

Security Restrictions
Once the ability to download dynamic components is built into the Java Wireless Client software, there are still restrictions upon its use. That is, the com.sun.midp.amsservices.AMSServices API enabled by building in this dynamic capability can only be accessed by a signed MIDlet suite belonging to the manufacturer domain (or by ROMized MIDlets). Any unsigned MIDlet attempting to use the API will cause a security exception to be thrown. Any MIDlet having the correct security permissions can request installation of a dynamic component in com.sun.midp.amsservices.AMSServices API installComponent interface, as shown in CODE EXAMPLE 14-7.
CODE EXAMPLE 14-7

The installComponent interface

public int installComponent(String url, String name) throws IOException, SecurityException;

Support for Clamshell Devices


The Sun Java Wireless Client software provides some support for clamshell devices, which have both an internal display (interactive when the device is open) and an external display (interactive when the device is shut). When porting to the a clamshell device, a switch can be implemented between the internal display and the external display.

Note The Sun Java Wireless Client software assumes that the internal and external displays have the same functionality and only one is active at a time. Other capabilities (for example, different functionalities per display) are not supported.
To enable or disable an external display, when the clamshell is closed or opened, the native platform should invoke the following function: javanotify_clamshell_state_changed(javacall_lcd_clamshell_state state) When the Java platform is notified, the virtual machine is switched to the new state. It then notifies the native platform that the switch has been made by invoking javacall_lcd_handle_clamshell().

Chapter 14

Application Management with the Java Platform

157

The Java platform can then query the JavaCall porting layer for new screen dimensions using the following functions:

javacall_lcd_get_screen_width() javacall_lcd_get_screen_height()

The dimensions returned are expected to be the appropriate size for the new screen display being activated.

Porting and Customizing


This section describes how to port and customize the Application Management Service (AMS) subsystem.

Strategies for Porting the AMS


Port the AMS in stages, initially using the default components. In later stages, replace the default components as desired. See the Build Guide for the option to use to eliminate AMS components from the build. Customization of the default components is discussed later in Strategies for Customizing the AMS on page 160. Because PCSL is used for suite storage, porting the default components is very simple and consists of the following high-level steps. 1. Select the location of the MIDP application database by calling the midpSetAppDir(<appDir>) and midpSetConfigDir(<confDir>) functions. 2. Optionally, change the APP_DIR and CONFIG_DIR constants in midp_dir/src/ams/example/ams_common_port/default/native/command LineUtil_md.c These constants can be changed to the desired subdirectories or to empty strings if the devices file system does not support subdirectories.

Note The APP_DIR and CONFIG_DIR constants are used only for non-JavaCall
ports.

158

Architecture and Design Guide December 2008

Strategies for Customizing the AMS


The Java Wireless Client software AMS subsystem can be customized in a number of ways. This section includes a list of things to be aware of when you consider customizing your AMS implementation. Following the list are some figures that illustrate the ways that you can configure your AMS.

Things to Consider
The following list includes things to consider if you plan to customize your AMS implementation.

For each component, decide whether to use the Java Wireless Client software implementation or create a custom version. If you use a native application manager, then you cannot use the Java Wireless Client software application manager. You can use the Java Wireless Client software installer or you can write a custom version. You can use the default Java Wireless Client software suite storage layer that uses PCSL file services, or you can write a custom version as long as you satisfy the suite storage API that the runtime depends on. For each Java Wireless Client software component, decide which customizations to perform. For example:

If you use the Java Wireless Client software suite storage implementation, you can customize the space requirement algorithm for the image cache in midp/src/ams/ams_base/reference/native/imageCache.c. Because space in persistent storage is typically limited, the default implementation of image cache provides a basic algorithm that ensures at least IMAGE_CACHE_THRESHOLD (defined in constants.xml) bytes of storage remain available during and after creation of the cache. Modify the following file to download MIDlets from an operator-configured or SIM-based URL instead of asking the user. midp/src/ams/ota/reference/classes/com/sun/midp /installer/DiscoveryApp.java

To add user billing, modify Installer.java. Replace Application Manager screens by implementing the AppManagerUI and AppSettingsUI interfaces. These are located in midp/src/ams/appmanager_ui/classes/com/sun/midp/appmanager. An alternative Application Manager UI implementation is discussed in AMS UI Implementation on page 161.

Chapter 14

Application Management with the Java Platform

159

To change the foreground and background policies, modify the following files: midp/src/ams/ams_base_cldc/reference/classes/com/sun/midp/ main/MIDletProxyList.java midp/src/ams/ams_base_cldc/reference/classes/com/sun/midp/ main/MVMDisplayController.java midp/src/ams/ams_base_cldc/reference/classes/com/sun/midp/ main/DisplayController.java.

AMS UI Implementation
The Application Manager consists of two parts. The first part is located in midp/src/ams/appmanager_base and represents the core functionality. The second part is responsible for the user interface and is located in midp/src/ams/appmanager_ui. The Application Manager screens are organized as an implementations of the AppManagerUI and the AppSettingsUI interfaces. To provide an alternative AMS UI implementation, the variable AMS_APPMANAGER_UI_IMPL_DIR should point to the directory where the implementation resides. By default, the Application Manager reference implementation is used. The Application Manager uses the following screens (all paths are to the reference implementation):

Main Displayable midp/src/ams/appmanager_ui/reference/classes/com/sun/midp/ appmanager/AppManagerUIImpl.java

MIDlet Selector screen midp/src/ams/appmanager_ui/reference/classes/com/sun/midp/ appmanager/MIDletSelector.java)

MIDlet Switcher midp/src/ams/appmanager_ui/reference/classes/com/sun/midp/ appmanager/MIDletSwitcher.java

Application Settings screen midp/src/ams/appmanager_ui/reference/classes/com/sun/midp/ appmanager/AppSettingsUIImpl.java

The main Displayable screen commonly contains a list of installed MIDlets and system MIDlets. This list is constructed by means of callbacks defined in the AppManagerUI interface (itemAppended and itemRemoved). It is up to the UI implementor to sort the MIDlets or show folders if the Folder functionality is supported (set USE_AMS_FOLDERS=true at build time).

160

Architecture and Design Guide December 2008

The AppManagerUI implementation is notified when a MIDlet is started, exited or its state changed. To launch, update, bring to the foreground, remove or show a MIDlets properties dialog, the AppManagerUI implementation should call the corresponding methods of AppManagerPeer. The MIDlet Selector screen contains the list of MIDlets from a specified suite. This screen is expected to be shown when the showMidletSelector() method of AppManagerUI is called. It should be possible to launch or exit a MIDlet from this list. The MIDlet Selector screen is used only for multi-MIDlet suites. The MIDlet Switcher screen allows you to switch between running applications by moving a selected application to the foreground. A dialog be shown when the showMidletSwitcher() method of AppManagerUI is called. The Application Settings screen is an implementation of the AppSettingsUI interface. On this screen, the permission settings of available MIDlets can be viewed and changed.

Configuration Examples
The following figures illustrate ways that you can customize your AMS implementation.

Default Implementation
FIGURE 14-2 shows the AMS configuration using the default Java Wireless Client software components. Note that the default suite storage implementation is replaceable as long a the API is maintained. You can use a custom suite storage implementation if the platform uses a native file viewer, or if the platform stores files in a custom format, or if it uses different file names.

Chapter 14

Application Management with the Java Platform

161

FIGURE 14-2

AMS Using Java Wireless Client Software Default Implementations


Java Wireless Client software runtime Java Wireless Client software installer

Suite storage API Java Wireless Client software or custom suite storage

Custom Installer
FIGURE 14-3 shows the AMS configuration using a custom installer.
FIGURE 14-3

AMS Using Custom Installer


Java Wireless Client software runtime Custom installer

Suite storage API Java Wireless Client software suite storage

Custom Installer and Custom Suite Storage


FIGURE 14-4 shows the AMS configured with both a custom installer and a custom suite storage implementation. The custom suite storage implementation supports a custom storage format.

162

Architecture and Design Guide December 2008

FIGURE 14-4

AMS With Custom Installer and Custom Suite Storage Implementation


Java Wireless Client software runtime Custom format

Suite storage API Custom suite storage implementation

Default Application Manager


FIGURE 14-5 shows the AMS using the default Java Wireless Client software application manager.
FIGURE 14-5

AMS With Default Java Wireless Client Software Application Manager

Java Wireless Client software app. mgr.

Java Wireless Client software runtime

Chapter 14

Application Management with the Java Platform

163

Custom Application Manager


The Sun Java Wireless Client software allows for implementation of a native Application Manager (NAMS), with all other components implemented in the Sun Java Wireless Client software. To control which components are implemented by the Sun Java Wireless Client software and which are implemented by the native platform, there are several build options that can be set. These include:

USE_NATIVE_APP_MANAGER USE_NATIVE_INSTALLER USE_NATIVE_SUITE_STORATE USE_NATIVE_RMS

For information on these build options and how to set them, see the Build Guide.

Native Application Manager Configurations


Two NAMS configurations are of particular interest:

The native Application Manager UI only The complete native Application Manager

The Sun Java Wireless Client software provides a sample implementation of the native Application Manager for the Windows platform. The path is: midp_dir/src/ams/example/nams_ui For directions on how to build the sample native Application Manager, see the Build Guide.
FIGURE 14-6 shows the AMS using a custom, native Application Manager that interacts with the runtime through the NAMS API.

164

Architecture and Design Guide December 2008

FIGURE 14-6

AMS With Custom Native Application Manager


NAMS API

Custom native app. mgr.

Java Wireless Client software runtime

Chapter 14

Application Management with the Java Platform

165

166

Architecture and Design Guide December 2008

15

MIDlet Auto Invocation


This chapter discusses the design and porting of the MIDlet auto invocation subsystem of Java Wireless Client software. The MIDlet auto invocation subsystem enables a MIDlet to be launched automatically at a particular time or when data arrives across a network connection. Launching an application to handle data arriving across a network connection is known as pushing data to the application. For that reason the subsystem is also referred to as the push subsystem. The MIDP 2.0 Specification allows a MIDlet to be invoked in one of the following three ways:

Manually by the user In response to an alarm (an absolute time at which the MIDlet is registered to be run) In response to the networking subsystem receiving a message for the MIDlet

The last two ways (alarms and networking) are referred to as MIDlet auto invocation and are handled by the MIDlet auto invocation subsystem.

Chapter 15

MIDlet Auto Invocation

167

The MIDlet auto invocation subsystem interacts with the subsystems and services listed in TABLE 15-1.
TABLE 15-1

Auto Invocation Subsystem Interactions


Interaction

Subsystem or Service

AMS subsystem

Scheduler - Finds out what MIDlets are running and has the current MIDlet suite object to check for permission to launch. Installer - Registers inbound connections for MIDlets, based on the JAD file. MIDletSuiteStorage - Starts MIDlets and gets MIDlet properties and interrupt settings. The MIDlet suite storage component uses the subsystems push registry component to remove a MIDlet suites connections when the suite is deleted. Checks with the push registry when a MIDlet opens or closes a connection type that supports push. Holds persistent lists of alarms and inbound connections. Handles the user interaction for granting permission to register connections and interrupt the current application.

Networking subsystem Storage service Security handler

The subsystem also requires access to the following device services:

System Timer - Gets the current time. The system timer must also signal the autoinvocation subsystem at a specified time in the future. The system timer must be able to be multiplexed with networking and I/O (mouse, keyboard, and painting) signals to avoid polling.

System Networking - Listens for signals from inbound messages, connections, or both. Network signals must be able to be multiplexed with timer and I/O (mouse, keyboard, and painting) signals to avoid polling.

Design
The MIDlet auto invocation subsystem must satisfy the push and alarm requirements of the MIDP 2.0 Specification and Java Technology for the Wireless Industry Specification. It also has the following goals:

Portability The system-dependent logic for listening for network data and the system timer must be separate from the general push connection list logic. Resource Conservation When listening for network data and the system timer, CPU use must be minimized.

168

Architecture and Design Guide December 2008

Prototyping and Test Development Support The MIDlet auto invocation subsystem must provide prototype connection implementations for device implementors and test developers. The example protocols are SMS, CBS, TCP, and UDP. Only the TCP and UDP prototypes work with the actual protocols and the SMS and CBS prototypes use UDP. See the Porting Users Guide for more information about SMS and CBS prototypes and porting Bluetooth push connections.

Design Overview
The MIDlet auto invocation subsystem has the following components:

Push Registry Provides persistent lists of alarms and inbound connections that can invoke MIDlets. The component gets persistent data storage from the storage service. The component is used by internal push listeners, applications, and installers. The push registry component has the following functionality:

Gets and uses information in the alarm list and push list Saves and restores the alarm and push lists Adds and deletes entries from the push list and the alarm list Finds what MIDlet to launch for an incoming connection or alarm Finds all of the incoming connections or alarms for a particular MIDlet

Internal Push Listener Handles inbound connections and alarms when MIDP is running. The internal push listener, running in its own thread, takes the following steps:

1. Waits on a native listening method that wakes up if either an alarm is triggered or data has arrived on a network port 2. Determines whether it must launch a MIDlet in response to the alarm or data. If it must launch a MIDlet, it proceeds to the next step. Otherwise, it goes back to Step 1. 3. Gets the parameters of the MIDlet to be launched. 4. If the source of the network data does not match the filter provided by the application, the push listener cannot get parameters. In this case, it goes back to Step 1; otherwise, it proceeds to the next step. 5. Determines whether the MIDlet to be launched is already running 6. If the MIDlet is already running, it determines the connection then goes back to Step 1. Otherwise, it proceeds to the next step.
Chapter 15 MIDlet Auto Invocation 169

7. Determines whether the user wants to launch the MIDlet and saves the answer. It does this using the current MIDletSuite object from the scheduler. 8. If the user does not want to interrupt the current MIDlet, it checks the connection then goes back to listening. Otherwise, it proceeds to the next step. 9. Sets the MIDlet to be the next MIDlet to execute by using the MIDletSuiteStorage API. 10. Uses the scheduler to shut down the current MIDlet suite. This stops the VM and triggers the loading of the next suite.

External Push Listener Handles inbound connections and alarms when MIDP is not running (not yet implemented).

Push Connection States


Push connections have the following states:

Available - Connection fields have been read from persistent storage, but no port has been allocated yet Checked In - Network port is allocated and being monitored for data by the listener Received Event - Push component has received a data-ready event on the port and the port is no longer being monitored by the listener Launch Pending - Network port has data from a source the MIDlet wants and the port is no longer being monitored by the listener Checked Out - The MIDlet is handling the network port and the port is not being monitored by the listener

FIGURE 15-1 shows the transitions between these states.

170

Architecture and Design Guide December 2008

FIGURE 15-1

Push Connections State Transitions

Available Port allocated

Checked in MIDlet closes the port Checked out User denies permission to launch MIDlet Source does not match filter Source matches filter

Data detected on the port

MIDlet opens port Launch pending

Received event

Design Rationale, Notes, and Considerations


The internal push listener blocks, that is, it does not sit in a polling loop to see whether events occur or alarm times have been reached. Instead, it interacts with the operating systems networking and timer APIs and is notified of events if they occur. This behavior is essential for conserving resources such as battery life. For portability, much of the push registry and internal push listener is designed and implemented in the Java programming language. Thread safety and permission handling rely on the Java platform. Thread safety is of special concern if the system is currently installing a MIDlet suite when an alarm or incoming connection occurs. The subsystem must ensure the consistency of the registry and thread safety, which is easier and more portable in the Java programming language than in native code.

Chapter 15

MIDlet Auto Invocation

171

Handling security permissions might require that an alert be displayed for the user. This is better done in the Java programming language, because KNI does not permit callbacks into the Java platform layer.

Porting
You must always port the push registry, which has a native porting interface. See the Native API Reference for information. You can port the push listener components in stages. Port the internal push listeners alarm-based invocations followed by its network-based invocations, then implement the external push listeners alarm-based invocations followed by its network-based invocations. The external push listener component, which handles push notifications and alarms when the virtual machine is not running, is not implemented. You must design and implement this component at porting time. The MIDP 2.0 Specifications class documentation for the push registry outlines what is expected of a device in order to support push notifications and alarms. A target device can provide push functionality in several ways. The following issues can affect your design:

Which protocols that the target device accepts How MIDP listens for messages Buffering Whether the target device supports running multiple MIDlets concurrently How you handle user interaction

Protocols
The networking subsystem makes certain protocols available to the MIDlet auto invocation subsystem. You can use one or more of these protocols to accept pushed messages. For example, a MIDlet might use server sockets if they are supported on a target device with a permanent IP address. You can also add protocols, such as the Bluetooth protocols specified in Java APIs for Bluetooth (JSR 82). See Adding Network Protocols for Push on page 174 for more information. When you determine which protocols to use for push, keep the following requirements in mind:

It must support static external identification like a phone number or IP address. For example, do not choose a socket or datagram if each deployed device is not assigned a globally unique Internet address.

172

Architecture and Design Guide December 2008

It must have separate channels or ports. For example, do not choose the comm protocol, because there is only one serial port.

Listening for Incoming Data


MIDP must listen for inbound connection notifications, so that it can launch a MIDlet to handle the incoming message. It can listen using native blocking or a polling mechanism. Native blocking is preferable. When the code for listening is external to the VM, the code can be simpler because it does not have to cooperate with the GUI. On most platforms you can use a timed network wait mechanism.

Message Buffering
The requirements for message buffering are protocol specific. Some protocols require it but others do not. What is required is that if your port buffers messages, it must provide them to the launched MIDlet when the MIDlet opens the push connection. Supporting datagram connections for push requires buffering of at least the first message. Your implementation must be able to at least give the launched MIDlet the datagram that caused it to start. Supporting socket connections for push does not require any message buffering. Your port must only ensure that the launched MIDlet can open the connection, and accept it if it has not timed out. Java Wireless Client software buffers the first message and the inbound connection sent to a MIDlet using the datagram protocol. It also accepts the inbound connection for a server socket. It uses the data from these operations to check whether the MIDlet registered to receive data from the messages source. It conducts this check before disturbing any running application. If your device has limited space resources, you might want to limit message buffering for some protocols. For example, if your device supports SMS messaging, you might be able to cache only a fixed number of messages.

Chapter 15

MIDlet Auto Invocation

173

User Interaction
The MIDlet auto invocation functionality cannot launch a MIDlet without the users acknowledgement. Users must be in control so that applications don't randomly disrupt what they are doing. The internal push listener requests the users permission before launching a pushed MIDlet. When you implement the external push listener, you must decide how to present the request to interrupt the currently running MIDlet. Add the requestpresentation code to the MIDlet suite loader, which is part of AMS. AMS is described in Chapter 14.

MIDlet Concurrency
Some devices can run multiple MIDlets concurrently, while others can run only one MIDlet at a time. Java Wireless Client software assumes the target device can only run one MIDlet at a time. When a MIDlet is started because of an incoming message or alarm and the user agrees to be interrupted, this component destroys the running MIDlet to launch the pushed MIDlet.

Adding Network Protocols for Push


To add a new protocol, follow these steps: 1. Add a protocol parameter, if required, to push native methods. If the new protocol does not share the handles the same way as the other supported protocols, add a protocol parameter like the one in the function pushcheckout to the functions pushcheckin, pushfindfd, and findPushBlockedHandle in push_server.c. 2. Test the change in Step 1 with the currently supported protocols. Do this before adding the new protocol. 3. Add a new case for the protocol to push native methods. Add the case to the functions pushProcessPort, pushDeleteEntry, pushcheckout, and pushfindfd. Also add it to the findPushBlockedHandle function, if you changed it in Step 1.

174

Architecture and Design Guide December 2008

4. In the native method that opens the protocols resource, check whether the resource is in use before opening it. In the native method that the protocols class uses to open the native protocol resource, call the pushcheckout function before opening the native resource. Only open the native resource if the pushcheckout function does not return a handle. 5. In the native finalizer and native method that closes the protocols resource, check whether the resource is being used before closing it. Add a call to the pushcheckin function before closing the native resource and only close the native resource if pushcheckin does not return successfully. 6. Provide special handling for opening a connection and reading if your protocol does not allow peeking. Peeking is the ability to read data but not mark the data as read. If your protocol does not support peeking, modify the native method that reads data (or accepts a connection) to get the data (or connection) cached by the function pushfindfd and only read (or accept a connection) if no data (or connection) is cached.

Chapter 15

MIDlet Auto Invocation

175

176

Architecture and Design Guide December 2008

16

Runtime Security
This chapter discusses the design and use of the runtime security service. The runtime security service restricts a MIDlet suite from using other MIDlet suites classes and from using internal system-only classes. Runtime security refers to any code in the system that protects restricted methods from unauthorized access. All internal code depends on the runtime security service. Before you port the runtime security service, become familiar with CLDC HotSpot Implementation. The runtime security service has the following requirements:

External MIDlet suites must be restricted from the code of other suites. External MIDlet suites must not be permitted to call restricted internal system methods. Internal MIDP classes must still be able to access the methods they require, across package boundaries, even if the running MIDlet is not permitted to run those methods directly.

In addition, the runtime security service includes the following goals: Small Security cannot be turned off to save space, unlike the Java SE platform. Fast Security cannot be turned off to improve performance, unlike the Java SE platform. Unobtrusive Implicit techniques, used whenever possible, keep the number of explicit security checks to a minimum. The runtime security service is incorporated into the following components, each of which fulfills part of the subsystem requirements:

Native virtual machine (VM) startup code and MIDlet suite loader Class loader

It also defines one object, the security token.

Chapter 16

Runtime Security

177

Design Considerations
The following sections describe aspects of the runtime security system that are important for you to know about when you port it to your device.

Native VM Startup Code and MIDlet Suite Loader


Java Wireless Client software restricts a MIDlet suite from accessing the classes of other suites by putting only that MIDlet suites JAR file in the class path before starting the virtual machine. The MIDlet suite loader can then only load the MIDlet suites own code when it loads the classes for running a MIDlet from the MIDlet suite.

Class Loader
The runtime security service must keep external MIDlet suites from calling restricted internal system methods. Some protection is provided by the Java programming language itself, which by default restricts access to a method or field by requiring that the caller be in the methods package or fields package. This is commonly called package-private access. Applications in the Java Platform, Standard Edition (Java SE platform) environment circumvent package-private access by defining classes in system packages. Applications cannot be permitted to use this workaround in MIDP, as it leads to security checks between classes in the same package. The additional security checks increase the amount of security code and decrease Java Wireless Client softwares performance. To keep applications from defining classes in system packages, Java Wireless Client software modifies the system class loader so that it loads internal packages only from ROM. Because Java Wireless Client software keeps application-defined system classes from ever being loaded, even if an application defines a system class.

178

Architecture and Design Guide December 2008

Security Token
Java Wireless Client software must restrict the access of an external MIDlet suite to resources intended for its use, but a permissible call from a MIDlet might result in a call to an internal class that has more access. Java Wireless Client software must enable internal classes to perform a larger set of actions than the MIDlet calling them. Java Wireless Client software defines a security token object to enable internal classes to perform sensitive actions. At initialization time, an internal security token is created and is passed to the internal classes that need it. Restricted internal methods take a security token as an extra argument and they check it before performing their task. Internal methods can call restricted functions because they have a security token, but external MIDlets cannot call restricted functions directly because they do not have (and cannot obtain) a security token. A MIDlets access to restricted functionality is limited, whereas an internal methods access is not.

Using the Service


This section contains advice on writing internal classes that are protected by a security token and writing internal classes that are used by optional internal MIDlets (such as classes used by the OTA installer).

Classes Protected by Security Tokens


When you design a class that is protected by a security token, check the security token during the construction of the class rather than checking it in method calls. This minimizes the number of security checks, which improves the size and performance of your port without jeopardizing security. To follow this advice, write methods that would normally be static as instance methods. An instance method does not require a security check because the check is done when the instance is created. In contrast, a static method requires a security check because it is called on the class and the security check in the constructor does not apply.

Chapter 16

Runtime Security

179

Classes Used by Internal MIDlets


As you port the Java Wireless Client software, you might create classes that optional internal MIDlets use. An internal MIDlet, such as the OTA installer, provides a system function. Internal MIDlets are part of the Java Wireless Client software and users do not download them. When you design a class that an internal MIDlet uses, do not protect access by requiring a security token. Internal MIDlets do not have security tokens because they are applications, not system classes. No applications, even internal applications, have security tokens. Instead of requiring a security token, protect access to your class by using the permission protection service. This is the same protection service that other MIDlet suites use, but you can give your internal MIDlet broader permissions. See Using Permissions for Internal MIDlets on page 187 for information.

180

Architecture and Design Guide December 2008

17

Permission Management
This chapter discusses the design, extension, and use of the permission management service. The permission management service implements the security model described in the MIDP 2.0 Specification and JTWI Specification.

Note This service is typically not ported.


To implement the security model described in the MIDP 2.0 Specification, the permission management service protects security-sensitive APIs by checking the permissions of MIDlet suites. It handles push-interrupt queries so that a MIDlet is only launched to handle an incoming message if the MIDlet is authorized to do so. Subsystems with MIDlet-accessible security-sensitive APIs depend on the permission management service. The permission management subsystem depends on the following subsystems:

MIDlet suite loader - Assigns the initial permissions to the internal MIDlet suite. Java Wireless Client softwares internal MIDlet suite provides system services such as a graphical installer. See Chapter 14 for more information on the internal MIDlet suite. Storage service - Holds the security information for the MIDP implementation. See Chapter 8 for more information. Application management system:

Installer - Authenticates MIDlet suites and assigns their initial permissions. Scheduler - Acts as the anchor of trust for the permission management service. Each MIDlet suite has its own Scheduler. Application manager Interacts with users to update permissions for installed MIDlet suites.

See Chapter 14 for more information.

Chapter 17

Permission Management

181

High-level user interface Interacts with the user to request authorization. For example, the display manager provides a way to preempt the display to ask the user questions about a permission. See Chapter 11 for more information.

Design Overview
The permission management service has two components: the security handler component and the permissions component. The security handler component ensures that a MIDlet suite can perform only the actions for which it was authorized. The permissions component provides names, questions and answers for each permission, as well as supplying the initial permissions for each domain to the installer.

Security Handler
The security handler component ensures that a MIDlet suite can perform only the actions for which it is authorized. The security handler depends on the following components:

AMS secure installer component, which determines whether the current MIDlet suite is trusted. Scheduler of the AMS runtime environment component, which checks whether the current MIDlet suite is permitted to run a restricted method. Restricted methods use the scheduler and only complete their tasks if they receive authorization. Permissions component (see Permissions on page 182) that interacts with restricted methods and the scheduler to determine whether the current suite is permitted to perform a particular action. High-level user interface subsystem (see Chapter 11) that provides I/O to ask the users permission when the MIDlet suites permission level indicates that the query is required.

Permissions
The permissions component implements the permission levels defined in the MIDP 2.0 Specification and controls how those permission levels are presented to the user. It uses the high-level user interface subsystem to present the information to the user.

182

Architecture and Design Guide December 2008

The MIDP 2.0 Specification defines the permission levels allow and never, as well as three user-interaction levels for MIDP permissions: blanket, session, and one shot. Each level has a possible value of yes or no. The blanket level has the additional value of not asked. TABLE 17-1 summarizes the internal permission levels associated with the MIDP 2.0 Specification permission levels and their values.
TABLE 17-1

Permission Level
Description

Permission Level

Allow Never Blanket Blanket granted User denied Session Session denied One shot Denied

Yes, and do not allow the user to change the level No, and do not allow the user to change the level The user has not been asked; ask once Yes, and do not ask again No, and do not ask again Yes, and do not ask until next use of the application No, and do not ask until the next use of the application Yes, and ask the next time the API is called No, and ask the next time the API is called

When Java Wireless Client software presents a permission request to the user, it uses the high-level user interface component to present runtime-security dialog screens with yes-or-no questions. If the user chooses yes, the MIDlet proceeds normally (yes grants a permission). If the user chooses no, a security exception is thrown (no denies permission). In addition to answering questions as a MIDlet suite runs, users must be able to change the user-interaction levels associated with installed MIDlet suites as part of application management. For this task, the permissions component uses the application manager to present the users with settings screens. It enables changes to a permission function group, rather than a change to a single permission. A permission function group is defined in the JTWI Specification, and consists of multiple permissions grouped by similar function.

Chapter 17

Permission Management

183

The JTWI Specification dictates the permission levels allowed for each permission function group in the untrusted domain. The permission levels map to the internal permission levels shown in TABLE 17-2.
TABLE 17-2

Java Technology for the Wireless Industry Permission Levels


Permitted Internal Permission Levels

Permission Level

Blanket Session

All permission levels except allow and never (allow and never are not user permission levels) User denied Session Session denied One shot Denied

One shot

User denied One shot Denied

Design Rationale, Notes, and Considerations


The permission management service is implemented in the Java programming language to speed development time, ensure high quality, and provide deviceindependent code. In addition to being device independent, most of the service is also independent of specific permission domains. If you add a new domain or change an existing one, you do not need to change the restricted APIs and the security dialog screens. The exception to domain independence is the permission component. Some of its code relies on domain names.

Policy Configuration
The configuration of security policy is loaded by calling to the native API instead of being hard-coded (in the Permissions class in the com/sun/midp/security package). This enables the option to change the security policy configuration without the need to rebuild the VM image. The parameters that are loaded are:

domain names group names group permissions permission levels for each group

184

Architecture and Design Guide December 2008

messages used in the dialog boxes

Implementations
Currently there are two security policy implementations:

javacall platform - Contains functionality for loading conguration data from les on the le system. Found in the le javacall/implementation/win32_emul/midp/permissions.c static (non-javacall) platform - Contains a policy conguration that supports MSA 248-compliant platforms. Found in the file midp/src/security/midp_permissions/reference/native/ generic_policy_load.c

Two new configuration property values are defined:

security.policyfile - The name of the file that contains the policy configuration data. The default value is: security.policyfile = _policy.txt security.messagefile - The name of the file that contains the messages of each group. The default value is: security.policyfile = _function_groups.txt

The policy files must be located in the config folder on the target device. The midp build (midp/build/common/makefiles/MIDP.gmk) copies two policy configurations (MSA, JTWI) to the out/midp/appdb folder.

New Permissions
The MIDP 2.0 Specification enables an implementation to add specific permissions as long as they are not in the javax namespace. For example, you can add a new permission to allow your device-specific public MIDlets to access a non-standard protocol.

Adding a New Permission


You add a new permission by using the permission extensions mechanism. Follow these steps to add a new permission:

Chapter 17

Permission Management

185

1. Create an XML file with your permission definitions, as shown in CODE EXAMPLE 17-1.
CODE EXAMPLE 17-1

Permission Extension.

<configuration> <permissions> <group ID=READ_USER_DATA_GTOUP> <permission ID=MY_READ_PERMISSION Name=com.my_company.util.Read/> </group> </permissions> </configuration>

Note There are no naming conventions for permissions. However, they should
describe, as concisely as possible, the tasks they protect. 2. Add the newly-created file to the list of extended permissions, like this: PERMISSION_EXTENSIONS_LIST+$(MY_COMPONENT_DIR)/src/share/ config/permissions.xml 3. Add the new permission string to the appropriate group in the policy file: midp/src/security/midp_permissions/reference/ config_policy.txt.JTWI or midp/src/security/midp_permissions/reference/policy.txt.MSA 4. If your new permission does not fit into an existing group of permissions, perform the following tasks. a. Add a new group in the policy file and add the new permission string to the group. b. Add the new group to each domain (listed at the end of the policy file) with the appropriate permission value. c. Add the new group to the Group list in the file. For example, midp/src/security/midp_permissions/reference/config/ _function_groups.txt/JTWI d. Add five strings to this group, in the following order:

The group visible name Question for the Setting dialog Setting disable choice string

186

Architecture and Design Guide December 2008

Title for the Runtime Permission dialog - This title is used for the dialog box that enables the user to set the user-interaction level of the permission. Question for the Runtime Permission dialog - This question is used for the dialog box that enables the user to set the user-interaction level of the permission.

New Domains
If you need a new domain, add it to the policy file: midp/src/security/midp_permissions/reference/config/ _policy.txt.JTWI or midp/src/security/midp_permissions/reference/config/ _policy.txt.MSA

Adding a New Domain


To add a new domain to the Permissions class, follow these steps: 1. Add a new string constant (a public static final field) that names the domain. The convention for naming the constant is domainName_DOMAIN_NAME. 2. Modify the forDomain method to set the initial permission levels for the domain.

Using Permissions for Internal MIDlets


To enable system applications (such as the graphical installer) to be developed in the Java programming language, system resources must be made available to them. Java Wireless Client software implements additional permissions to ensure that only system applications can use these resources. The permission names are com.sun.midp and com.sun.midp.ams.

Chapter 17

Permission Management

187

Java Wireless Client software gives the additional permissions only to the internal MIDlet suite. This enables system applications to use the MIDP permission checking system, as described in Chapter 17. If you write a new system MIDlet, add it to the internal MIDlet suite so that it also receives the additional permissions.

Finding the Status of a Security Certificate


The Online Certificate Status Protocol (OCSP) enables an installed application to determine the state of a security certificate by querying whether the certificate is valid or has been revoked. An OCSP client (for example, an application that receives a JAR file with a signed certificate) can issue a request to the issuer of the certificate for confirmation of its validity, then suspends acceptance of the certificate until the issuer indicates that the certificate is still valid. The OCSP Specification defines the data that must be exchanged between an application checking the status of a certificate and the server providing the status. In structuring an OCSP request, the receiving application must include the following information:

Protocol version The request for confirmation of the certificate The target certificate identifier (that is, the recipient of the request for confirmation)

Upon reception, the certificate identifier determines if the request for confirmation is correctly formed. If it is, the certificate identifier returns information about the certificate being queried, or returns an error message. If a specific signed certificate is valid, the validity of the certificate is confirmed. If the private key of the certificate has been compromised, or for other reasons the certificate has been revoked (of example, the date of the certificate has expired), this non-validity is also confirmed. Once the application issuing the request for confirmation of a signed certificate receives an OCSP response from the target certificate identifier, the application can reject the signed security certificate and cancel the transaction (for example, a download procedure) or accept the certificate anyway and continue with the operation. For more information, see the X.509 Public Key Infrastructure Online Certificate Status Protocol Specification.

188

Architecture and Design Guide December 2008

18

Native Resource Management for Multitasking


The Java Wireless Client software includes a native resource manager that tracks the use of native resources by each task1. The native resource manager enforces the systems native resource policy. The following two policies are provided by Java Wireless Client software:

Fixed resource policy Open resource policy

Refer to the Multitasking Guide for more information about multitasking and how to set the resource policy at build time.

Fixed Resource Policy


System resources are limited, and one way to ensure that they are allocated fairly is to use a fixed-partition resource management policy. This policy evenly divides the resource between the tasks. The maximum number of tasks is fixed. When the system launches the AMS, the system allocates and reserves all system resources required for the AMS task. The amounts are equal to the AMS task resource limits as defined in the constants XML file. When the system launches a user MIDlet in a new task, the system allocates and reserves all system resources. Each task used by different MIDlets gets the same amount of system resources. The resource amounts are equal to the tasks resource limits and are set in the constants XML file.
1. At the Java platform level, each separate running Java platform application (Java application) within one virtual machine is called a task. The API used to instantiate each task is a stripped-down version of the Isolate API defined in JSR 121. See The CLDC HotSpot Implementation Architecture Guide for more information.

Chapter 18

Native Resource Management for Multitasking

189

If the Java AMS service cannot reserve enough resources, it does not launch a new task. The application manager then tells the user that the application cannot be started due to the resource limit. If the native AMS (NAMS) service cannot reserve enough resources, it gets an error with a reason code through the callback mechanism and must report the failure to the user. With this policy, the maximum number of MIDlets that can run concurrently is always the same because all system resources are equally distributed between user tasks. The system tracks native resources and the Java application environment heap on a per-task basis. Note that certain resources are managed differently on different platforms. For example, images are managed as a native resources on Linux platforms, but are managed as part of the Java application environment heap on Windows platforms.

Open Resource Policy


In this use case, all system resources are divided into two pools. The AMS pool is allocated and reserved for the AMS task, and the application pool is shared among all application tasks. This policy treats memory differently than other resources in the application pool. It always provides a task enough memory to bootstrap in order to handle error conditions. As with the fixed resource policy, the AMS task has a separate system resource limit. The rest of the system resources (except memory) form an application resource pool where resources are open for competition. Each resource in the pool has its own resource limit defined in the constants XML file A minimum amount of memory required to start an application task must be identified and set in the XML file during porting. The system guarantees the specified minimum amount of memory for any running application task at any time. Memory above the reserved minimum is open for competition among all application tasks. The system tracks native resources and the Java application environment heap on a per-task basis. Note that certain resources are managed differently on different platforms. For example, images are managed as a native resources on Linux platforms, but as part of the Java application environment heap on Windows platforms. Images on Windows platforms are not managed as a native resource. As in the fixed policy, the Java AMS service does not launch a MIDlet if it runs out of resources. The application manager informs the user that the application cannot be started due to a resource limitation. The native AMS behaves the same as the Java AMS under the open policy.

190

Architecture and Design Guide December 2008

Porting
When you port a subsystem that manipulates a shared native resource, you must determine the following:

Which resource policy to use Whether the resource manager tracks that resource Where in the subsystem the resource is allocated and released How to reclaim the resource when a task exits

To determine if the resource manager tracks a particular resource, look for the resource in the enum in the midpResourceLimit.h file. Several native resources, such as networking and file handles, are already defined. If the native resource is not already defined, add it to the enum and add a new set of policies to the constants XML file. If the resource is already defined, set the corresponding values in the constants XML file to reflect the number of instances of the native resource and the policy for the resource on the target platform. Next, identify where in the subsystem the resource is allocated and released. For example, file handles are allocated when a file is opened and released when the file is closed. Place calls from the resource managers API in the places where the resource is allocated. At each location, use one call to determine if the allocation can succeed and another to decrement the amount available when the allocation succeeds. Place calls from the resource managers API in the places where the resource is released. At each location, use a call to increment available resources. You must also determine the correct error condition or exception to return if the allocation fails. For example, if all of the file handles are being used, the file open fails and throws an IOException to the invoking code. This is reasonable because all code that does I/O is already prepared to handle an IOException. Finally, you must reclaim a tasks native resources when the task terminates. One common way to do this is by associating the native resource with a Java object that has a native finalizer. The native finalizer checks to see if the native resource must be released. If the finalizer releases the native resource, it must also increment the available resource count in the native resource manager. When you complete all four steps, the native resource manager properly accounts for the resource and enforces your management policy.

Chapter 18

Native Resource Management for Multitasking

191

192

Architecture and Design Guide December 2008

19

Porting the Networking Subsystem


This chapter describes how to port the networking subsystem of the Java Wireless Client software. The networking subsystem consists of the set of classes that implement the networking protocols. Applications use these protocols using the Generic Connection Framework (GCF), and each protocol provides a class that implements the javax.microedition.io.Connection interface.

Note Protocols required by the any of the optional packages are discussed in the
appendix or chapter that describes how to port the optional package.
TABLE 19-1 lists the protocols that the networking subsystem provides to Java Wireless Client software.
TABLE 19-1 Protocol

Networking Subsystem Protocols


Description

SocketConnection ServerSocketConnection DatagramConnection SecureSocketConnection

Client connection to a TCP server. Server for TCP clients. Interface for sending and receiving UDP datagrams. Socket connection with SSL 3.0. Java Wireless Client software supports RSA RC4 128 and 40 bit cipher suites and does not support client authentication. Socket connection with the HTTP 1.1 protocol. The connection supports persistent connections, chunked data, and tunneling. HTTP connection that uses an SSL connection instead of an unsecured socket connection.

HttpConnection

HttpsConnection

Chapter 19

Porting the Networking Subsystem

193

The networking subsystem depends heavily on PCSL for its underlying networking implementations, and much of the networking subsystem is written in the Java programming language. Once PCSL is ported, most of the networking subsystem can be brought up quickly. See Chapter 8 for details about porting PCSL. The push subsystem has some interdependencies with the networking subsystem. Networking protocols for which push functionality is provided must be supported in the networking subsystem. For example, if push support is provided for server sockets, then server socket support must also be provided in the networking subsystem. For each protocol with push support, the push registry provides functions that hand off network connections and any cached data to the networking subsystem. The networking subsystem uses the functions when the pushed MIDlet opens a connection. See Chapter 15 for more information about the push subsystem.

Generic Connection Framework and Protocol Implementations


The networking subsystem is built on CLDCs GCF. See the documentation for the javax.microedition.io.Connector class in the CLDC specification. The connection that corresponds to the scheme from the URL passed to the Connector.open() method is implemented by instantiating a class named Protocol that resides in the Java programming language package com.sun.midp.io.j2me.scheme. For example, if an application calls Connector.open("http://www.example.com"), the scheme is http. The entry point for the implementation of this protocol is found in the class com.sun.midp.io.j2me.http.Protocol.

194

Architecture and Design Guide December 2008

The set of Java classes in this area use the common features listed in TABLE 19-2.
TABLE 19-2 Feature

Common Features Used by Java Classes


Description

StreamConnection interface ConnectionBaseInter face interface

All of the necessary functionality, except for the native interface to a native resource. The interface covers the many subtle, easily overlooked details in implementing the interface. All dynamically loaded protocols must implement this interface. The implementation supplies common functionality. For example, it disconnects only when the connection and all streams are closed, and throws an exception when a method is called after the connection is closed. Because some protocols have common buffering requirements, the networking subsystem provides classes with input and output buffering. For native resources that do not allow peeking ahead in the buffer, the subsystem provides an implementation that reads ahead into the input buffer. On some platforms, network protocols require native initialization before the network can be used. For these protocols, the networking subsystem provides a class in the com.sun.midp.io package that performs the native method call to initialize the network.

Common buffering requirements

Network Initialization

Some of the networking protocols are written entirely in the Java programming language and depend only upon other networking protocols. These protocols do not require any explicit porting and are simply configured into or out of the system. Other networking protocols have native interfaces and might require additional porting effort. This point is covered in the following steps for each networking protocol.

Porting the Networking Subsystem


The following high-level steps represent a reasonable path to port the networking subsystem. More detailed information is provided in the following sections. 1. Port PCSL. PCSL has native-level support for basic networking utilities (for example, host name lookup), sockets, and datagrams. PCSL porting is covered in Chapter 8. Implementing basic networking utilities and sockets is required, but the datagram implementation is optional.

Chapter 19

Porting the Networking Subsystem

195

2. Port the Socket protocol. The Java platform classes that implement the socket protocol have native interfaces that are implemented in by means of calls to PCSL. The Java programming language level socket protocol is in turn used by higher-level protocols such as HTTP and SSL. 3. Port the HTTP protocol. The HTTP implementation is a pure Java programming language implementation (Java implementation) that relies only on the Java implementation of the socket protocol. Having TCP and HTTP available enables automated testing using the HTTP AutoTester. In addition, when the AMS is ported (see Chapter 14), the Graphical Installer uses HTTP to support OTA installation and manual testing.

Note HTTP is the only protocol required to be supported in MIDP 2.0. Other
protocols are optional. The following steps can therefore be performed in any order, or not at all, depending upon which protocols you decide must be supported in your port. The exception is that HTTPS depends upon SSL having first been implemented. 4. (Optional) Port SSL protocol. The critical cryptographic functions of SSL are implemented in native code. The source code to the native implementation and the corresponding porting interface are optionally available. The protocol functions of SSL (for example, the handshake) are implemented in the Java programming language on top of the socket protocol implementation. 5. (Optional) Port the HTTPS protocol. The HTTPS implementation is written in the Java programming language directly on top of the HTTP and SSL implementations. If these protocols are implemented, the HTTPS implementation can be brought up immediately. 6. Port the UDP Datagram protocol. The Java classes that implement the datagram protocol have native interfaces that are implemented by means of calls to PCSL. Port the PCSL datagram implementation now if you have not done so already. The Java implementation of datagrams can then be integrated. 7. (Optional) Port the server socket protocol. The server socket implementation has its own native interface that must be ported. In addition, the server socket implementation also requires basic networking utilities from PCSL.

196

Architecture and Design Guide December 2008

General Porting Considerations


Some of the Java implementations of the networking protocols use buffering to increase performance. This consumes about 4 kilobytes of Java platform heap memory per connection. Some of the protocol implementations depend upon each other. This implementation dependency is reflected in the APIs exposed to applications. For example, the HTTP implementation uses the socket protocol implementation. Because the socket protocol implementation is present, this implies that the socket: protocol is visible to the application through the GCF. HTTP support is required, but if socket support is not provided to applications, additional work is necessary. Access to the socket: protocol must be disabled by modifying the javax.microedition.io.Connector class. This class is provided as part of the CLDC HotSpot Implementation source bundle. Similar dependencies exist between SSL and the socket protocol, and between HTTPS and SSL.

Porting Considerations for HTTP


This section discusses porting issues that might arise with the HTTP protocol involving HTTP proxies and persistent connections.

HTTP Requests Using Proxies


Java Wireless Client softwares HTTP implementation can make requests through a proxy server. To have the device emulator use a proxy server, set the internal system property com.sun.midp.io.http.proxy. See the Build Guide for more information. The HTTP implementation requires that HTTP proxy servers support the generic tunneling mechanism for TCP-based protocols through web proxy servers. Tunneling is used instead of the normal HTTP proxy because many proxies cannot handle certain advanced HTTP 1.1 features correctly and because tunneling is already implemented for HTTPS. If you modify the HTTP porting-ready implementation to use a WAP gateway, the WAP gateway replaces the proxy access. To do this, replace references to the generic HTTP proxy with calls to a native WSP stack.

Chapter 19

Porting the Networking Subsystem

197

HTTP1.1 Persistent Connections


The MIDP 2.0 Specification supports HTTP 1.1 persistent connections.

Note Do not change the porting-ready implementation to only include HTTP 1.0
connection behavior. Persistent connections have many advantages, but on small devices with limited resources they can be a problem if they are not closed properly. Java Wireless Client software solves this problem by using the value of an internal system property to set the time that a connection can remain open and unused. After the time limit, Java Wireless Client software closes the connection and removes it from the connection pool. The default value of the internal system property com.sun.midp.io.http.persistent_connection_linger_time is 60,000 milliseconds. Change it for your device, if necessary. See the Build Guide for information about configuring internal system properties.

Porting Considerations for HTTPS


This section discusses porting issues that might arise with the HTTPS protocol involving HTTPS proxies and persistent connections.

Porting HTTPS
Java Wireless Client softwares implementation of HTTPS extends its HTTP implementation. It uses SSL to make secure connections and uses the sample web public key store for CA certificates. Java Wireless Client softwares HTTPS implementation is compliant with HTTP over TLS as specified in RFC 2818, except that it uses SSL 3.0 instead of TLS 1.0 (SSL 3.1).

Note Java Wireless Client softwares implementation of HTTPS does not expose
an API to control the handshake listener. Exposing such an API allows certain certificate errors to be overridden by higher level applications. It must not be possible for an end user to override policy decisions about expired certificates. For security reasons, your port must not expose this API either. If you do not export this API, it is compliant with the MIDP 2.0 Specification.

198

Architecture and Design Guide December 2008

Using the Java Wireless Client Software SSL Implementations


The Java Wireless Client software SSL implementation is provided for reference purposes and is not intended for production use in devices. However, if the reference SSL reference implementation is used in a device you must provide secure random data in the com.sun.crypto.PRand class. Java Wireless Client software does not provide secure random data. Its seed is based on time, which is predictable. You must change it so that it obtains an initial 128 bytes (not bits) of unpredictable data from your native platform. Use RFC 1750 Randomness Recommendations for Security as a guide for collecting the initial data. See http://www.ietf.org/rfc/rfc1750.txt.

Porting Considerations for Server Socket


The server socket protocol has its own native interface. To port the server socket implementation, you must provide implementations of the functions defined in the header file serverSocketProtocol.h. The server socket implementation also relies on the basic networking utilities of PCSL, so PCSL must be present as well. See the Native API Reference for further details.

Network Monitoring
The network monitoring feature of Sun Java Wireless Client software allows you to send information about significant protocol events to your runtime implementation when a MIDlet is run in Debug mode. This feature can be enabled for MIDP and for selected optional packages, such as Multimedia Message Service and Bluetooth, and is passed via the Lime mechanism. To turn on the network monitoring function, you must build the JavaCall and MIDP components with the build option USE_NETMON=true. For more information, see the Build Guide. When a MIDlet callsconnector.open(scheme:address), the VM constructs a class name string consisting of the following elements: System.getProperty(javax.microedition.io.Connector.protocolpath) + System.getProperty(microedition.platform) + Scheme + Protocol

Chapter 19

Porting the Networking Subsystem

199

Note The default for microedition.platform is j2me.


When the network monitoring functionality is off, the value of the property javax.microedition.io.Connector.protocolpath is com.sun.midp.io. When the network monitoring functionality is on, the value of the javax.microedition.io.Connector.protocolpath is com.sun.kvem.io. Network monitoring classes extend the appropriate MIDP classes. When override methods from a parent class are called, they send event notifications to your runtime platform.

Note Network monitoring does not contain any platform-dependent code.


Details of network monitoring functionality are provided in TABLE 19-3 and
TABLE 19-4.
TABLE 19-3

Network Monitor Hooks (1) Child Class Method

Protocol & (Scheme) Multimedia Message Service (mms) Bluetooth Serial Port Profile (btspp)

Parent Class

com.sun.midp.io.j2me.mms. com.sun.kvem.io.j2me.mms send() Protocol .Protocol receive()

Bluetooth Logical Link Control and Adaptation Protocol (bt12cap)

com.sun.jsr082.bluetooth. com.sun.jsr082.bluetooth BTSPPNetmonConnec btspp.BTSPPConnectionImpl .kvem.btspp.BTSPPNetmonC tion() close() onnection sendO() com.sun.jsr082.bluetooth. com.sun.jsr082.bluetooth receiveO() btspp.BTSPPNotifierImpl .kvem.btspp.BTSPPNetmonN updateServiceReco otifier rd() close() com.sun.jsr082.bluetooth. com.sun.jsr082.bluetooth L2CAPNetmonConnec btl2cap.L2CAPConnectionIm .kvem.btl2cap.L2CAPNetmo tion() close() nConnection pl sendData() com.sun.jsr082.bluetooth. com.sun.jsr082.bluetooth receiveData() btl2cap.L2CAPNotifierImpl .kvem.btl2cap.L2CAPNetmo doClose() nNotifier updateServiceReco rd()

200

Architecture and Design Guide December 2008

TABLE 19-3

Network Monitor Hooks (1) Child Class Method

Protocol & (Scheme) Bluetooth Generic Object Exchange Profile (btgoep)

Parent Class com.sun.jsr082.obex.btgoe p.BTGOEPConnection com.sun.jsr082.obex.btgoe p.BTGOEPNotifier

Infrared Data Association Object Exchange (irdaobex) Transmission Control Protocal OBject EXchange (tcpobex) Cell Broadcast Short Message Service Short Message Service (sms) Application Protocol Data Unit (apdu) Java Card Remote Method Invocation (jsrmi)

com.sun.jsr082.obex.irdao bex.IrNativeConnection

com.sun.jsr082.obex.tcpob ex.TCPOBEXConnection

com.sun.jsr082.obex.kvem BTGOEPNetmonConne .btgoep.BTGOEPNetmonConn ction() close() ection write() com.sun.jsr082.obex.kvem read() .btgoep.BTGOEPNetmonNoti close() fier netmonUpdate() com.sun.jsr082.obex.kvem IrNetmonNativeCon .irdaobex.IrNetmonNative nection() Connection close() write() read() com.sun.jsr082.obex.kvem TCPOBEXNetmonConn .tcpobex.TCPOBEXNetmonCo ection() nnection close() write() read() com.sun.kvem.io.j2me.cbs receive() .Protocol

com.sun.midp.io.j2me.cbs. Protocol

com.sun.midp.io.j2me.sms. Protocol

com.sun.kvem.io.j2me.sms send() .Protocol

com.sun.midp.io.j2me.apdu .Protocol

com.sun.kvem.io.j2me.apd openPrim() u.Protocol

com.sun.midp.io.j2me.jcrm i.Protocol

com.sun.kvem.io.j2me.jcr openPrim() mi.Protocol invokeImpl()

Chapter 19

Porting the Networking Subsystem

201

TABLE 19-3

Network Monitor Hooks (1) Child Class Method

Protocol & (Scheme) Hypertext Transfer Protocol (http)

Parent Class

Secure Hypertext Transfer Protocol (https)

com.sun.midp.io.j2me.http com.sun.kvem.io.j2me.htt 1)create new .Protocol p.Protocol input/output stream 2)read/write one byte from/to the input/output stream 3)read/write buffer from/to the input/output stream 4)close input/output stream com.sun.midp.io.j2me.http com.sun.kvem.io.j2me.htt 1)create new s.Protocol ps.Protocol input/output stream 2)read/write one byte from/to the input/output stream 3)read/write buffer from/to the input/output stream 4)close input/output stream openPrim() disconnect() redBytesNonBlocki ng() writeBytes() setBaudRate() com.sun.midp.io.j2me.sock com.sun.kvem.io.j2me.soc openPrim() et.Protocol ket.Protocol open() disconnect() nonBufferedRead() writeBytes() setSocketOption()

com.sun.midp.io.j2me.comm com.sun.kvem.io.j2me.com Serial m.Protocol Communicati .Protocol on Protocol (comm)

Socket Protocol (socket)

202

Architecture and Design Guide December 2008

TABLE 19-3

Network Monitor Hooks (1) Child Class Method

Protocol & (Scheme) Serversock et Protocol (serversoc ket) Secure Socket Layer (ssl)

Parent Class com.sun.midp.io.j2me.serv ersocket.Socket

com.sun.kvem.io.j2me.ser (see Socket versocket.Protocol Protocol)

com.sun.midp.io.j2me.ssl. Protocol

Datagram com.sun.midp.io.j2me.data Protocol gram.Protocol (datagram)

com.sun.kvem.io.j2me.ssl openPrim() .Protocol close() read() write() setSocketOption() com.sun.kvem.io.j2me.dat openPrim() agram.Protocol send() receive() close()

Note The information provided in


provided in TABLE 19-3.

TABLE 19-4 is a continuation of the information

TABLE 19-4

Network Monitor Hooks (2) Lime Class MMSMsgReceiver Lime Method send received connect disconnect write read updateServiceRecord disconnect connect disconnected write read notifierDisconnect updateServiceRecord connect disconnect write read Data mms message url output data input data record data url output data input data service data record url output data input data

Lime Package com.sun.kvem.netmon.mms

com.sun.kvem.netmon.blue BluetoothMsgReceiver tooth

com.sun.kvem.netmon.blue BluetoothMsgReceiver tooth

com.sun.kvem.netmon.obex ObexMsgReceiver

Chapter 19

Porting the Networking Subsystem

203

TABLE 19-4

Network Monitor Hooks (2) Lime Class Lime Method Data

Lime Package

com.sun.kvem.netmon.blue BluetoothMsgReceiver tooth

notifierDisconnect notifierconnect url updateServiceRecord service data record connect disconnect write read connect disconnect write read open received close open send close open received close open exchangeAPDU url output data input data url output data input data

com.sun.kvem.netmon.obex ObexMsgReceiver

com.sun.kvem.netmon.obex ObexMsgReceiver

com.sun.kvem.netmon.sms

SMSMsgReceiver

input message url output message

input message url Connection status APDU command APDU response url APDU response method name, APDU respons APDU response url and direction byte buffer

com.sun.kvem.netmon.apdu APDUMsgReceiver

com.sun.kvem.netmon.jcrm JCRMIMsgReceiver i

open response invoke response

com.sun.kvem.netmon.http HttpMsgReceiver

newStream updateMsgOneByte updateMsgBuff close

204

Architecture and Design Guide December 2008

TABLE 19-4

Network Monitor Hooks (2) Lime Class Lime Method newStream updateMsgOneByte updateMsgBuff close Data url and direction byte buffer

Lime Package

com.sun.kvem.netmon.http HttpMsgReceiver

com.sun.kvem.netmon.comm CommMsgReceiver

connect disconnect read write setBaudRate connect

url and mode input data output data new baud rate url and mode //:port, READ_WRITE url and mode input data output data option name and value url and mode output data notification sends before receiving is started input datagram

com.sun.kvem.netmon.sock SocketMsgReceiver et com.sun.kvem.netmon.ssl SSLMsgReceiver

connect disconnect read write setSocketOption open send receive

com.sun.kvem.netmon.data DatagramMsgReceiver gram

received close

References
The following references are helpful when porting the networking subsystem:

RFC 1750. Randomness Recommendations for Security http://www.ietf.org/rfc/rfc1750.txt RFC 2246. The TLS Protocol http://www.ietf.org/rfc/rfc2246.txt RFC 2817. Upgrading to TLS Within HTTP/1.1. This RFC describes HTTP tunneling, among other topics http://www.ietf.org/rfc/rfc2817.txt RFC 2818. HTTP over TLS http://www.ietf.org/rfc/rfc2818.txt
Chapter 19 Porting the Networking Subsystem 205

WAP TLS Profile and Tunneling Specification. WAP-219-TLS-20010411-a. Wireless Application Protocol Forum Ltd., 2001 http://www.openmobilealliance.org SSL 3.0 Draft Specification, November 1996 http://wp.netscape.com/eng/ssl3/. Luotonen, A., Tunneling TCP Based Protocols Through Web Proxy Servers Also see the (expired) Internet draft draft-luotonen-web-proxy-tunneling-01.txt, published in Luotonen, A., Web Proxy Servers. Prentice-Hall, 1977.

206

Architecture and Design Guide December 2008

20

Porting the User Message Bundle Service


This chapter describes the design and porting of the message bundle service. Internationalization (I18N) is the process of designing an application so that it can be adapted to various languages, and regions without further engineering changes. The process of adapting the application to a particular language or region is referred to as localization (L10N).

Note The term internationalization is generally abbreviated as I18N because there


are 18 letters between the first i and the last n. The term localization is abbreviated as L10N because there are 10 letters between the l and the n. Java Wireless Client software provides a basic framework for I18N: the message bundle service. It is not the entire solution, but it eases localization by enabling you to add locale-specific components and translate text through either the Java layer or your platforms native layer. The message bundle service does not depend on other Java Wireless Client software services or subsystems. However, any Java Wireless Client software service or subsystem that displays information to the user uses this subsystem.

Design
The message bundle subsystem has three parts:

Access Retrieving the localized strings Locale-specific Content The strings retrieved by the access component

Chapter 20

Porting the User Message Bundle Service

207

Decoder-Encoder Getting and giving strings that have the proper encoding from and to the user

FIGURE 20-1 shows this information flow. The shaded box shows the porting layer for the message bundle service.
FIGURE 20-1

User Message Bundle Service Components and Interactions Get a string from a text box or field, or display a string

Request for a string to display

Access component of the user message bundle

Decoder-Encoder component of the user message bundle

Locale-specific content component of the user message bundle

Access Module
The access module holds the locale-independent code that includes the following components:

Constants associated with strings to be localized Functions that get the requested strings Specifications of the behaviors that all locales must handle

Behavior Module
The behavior module handles locale-specific content and behavior. It holds the strings for the default locale (en_US) and also acts as a template for localization. A new localized file is like the default locale, but with localized strings replacing the English text of the messages and localized behavior replacing the default behavior where appropriate.

208

Architecture and Design Guide December 2008

Decoder-Encoder Component
The decoder-encoder component ensures a proper translation between the character encoding used in the locale, and the unicode used internally. That is, when the system reads in bytes, it decodes them from the native languages character encoding to Unicode. Similarly, when the system provides output, it first encodes the Unicode strings into the character encoding of the native language. This component is not entirely in the user message bundle service. Parts of it are located in the CLDC HotSpot Implementation.

Design Rationale, Notes, and Considerations


This design has the following advantages:

It places all of the localized content and behavior in one file, which makes maintenance easier. It provides a discipline for adding new localizable strings that has these features:

Enables a compile-time check for the existence of the new localized string Ensures that the default file is always up-to-date. A localization expert can copy and localize the file, knowing that nothing is missing.

This design has the following disadvantages:

If a developer does not follow the conventions for localized strings, it is easier to accidentally enter duplicate identifiers. Unlike a missing string, this error is not caught at compile time. It does not support real-time locale change. The message bundle is determined when the MIDP runtime is started. It is not backward compatible with the MIDP reference implementation.

Porting
The messages of the locale-specific content component are in the com.sun.midp.l10n package. The messages have integer identifiers defined in the com.sun.midp.i18n package. The identifiers are organized into ranges that group the values based on the Java Wireless Client software subsystem.

Chapter 20

Porting the User Message Bundle Service

209

The following two scenarios might require you to update the message bundle service:

Adding message strings when you port other Java Wireless Client software subsystems. In this case you must change the locale-specific content component, as described in Adding Additional Message Strings on page 210. Supporting a new locale requires you to update the locale-specific content component, as described in Supplying Locale-Specific Strings on page 210. You might also need to update the decoder-encoder component, as described in Adding a Character Encoding on page 211.

Adding Additional Message Strings


To add a string, you must update both the message list and the identifiers. 1. Add the identifier for the message. If you add a string to an existing subsystem, maintain the identifier ranges. If you add a string for a new subsystem, add a new range. 2. Update the message list to add your new message.

Supporting a New Locale


Supporting a new locale involves one or both of the following tasks:

You must supply strings in the native locale for Java Wireless Client software to display to the user, as described in Supplying Locale-Specific Strings on page 210. If the new locale uses a special character encoding, such as Shift-JIS, you must modify the decoder-encoder component as described in Adding a Character Encoding on page 211.

Supplying Locale-Specific Strings


The locale-specific content component in the com.sun.midp.l10n package provides a class that holds strings for the default locale, en_US. Use the classs source file as a template. 1. Copy the file and name the copy LocalizedStrings_locale.java, where locale is the standard abbreviation for the locale. For example, a German localized strings file are named LocalizedStrings_de.java.

210

Architecture and Design Guide December 2008

2. Change the class name in the file to match the file name. 3. Replace the English text of the messages with localized strings. 4. Replace the default behavior with localized behavior (date formats, first day of the week, and so forth) where appropriate.

Adding a Character Encoding


The system property microedition.encoding holds Java Wireless Client softwares default character encoding. The property value is ISO8859_1. Java Wireless Client software uses the Java platform CLDC mechanism to implement a Java platform character encoding and has its own mechanism to implement a native layer character encoding.

Adding a Character Encoding in the Java Platform


Follow these steps to add a character encoding in the Java platform. 1. Create a directory to hold a new I18N module. Name the directory midp/src/i18n/your_new_module. 2. Create a classes/com/sun/cldc/i18n/j2me subdirectory in the new module. 3. Implement two classes per encoding. a. Put the classes in the com.sun.cldc.i18n.j2me package. Call the source files yourEncoding_Reader and yourEncoding_Writer. for example, ISO2022JP_Reader and ISO2022JP_Writer. Place the source files in your modules classes/com/sun/cldc/i18n/j2me subdirectory. b. Determine the superclasses for the new classes. If your reader and writer are stream based, have them extend com.sun.cldc.i18n.StreamReader and com.sun.cldc.i18n.StreamWriter. If your reader and writer are not stream based, have them extend java.io.Reader and java.io.Writer. c. Extend the superclasses methods. See the CLDC 1.1 Specification for the list of methods that must be extended.

Chapter 20

Porting the User Message Bundle Service

211

4. Add the new module to the build system. See the Build Guide for instructions.

Adding a Character Encoding at the Native Layer


Follow these steps to add a native implementation of a decoder and encoder: 1. Create a directory to hold a new I18N module. Name the directory midp/src/i18n/your-new-module. 2. Create subdirectories in your new module for native and Java platform layer code. The subdirectory for native code is share/native. The subdirectory for Java platform code is classes/com/sun/cldc/i18n/j2me. 3. Create a file to hold your native code. Call the file your_encoding.c. For example, ISO2022JP.c 4. In the new file, implement the API specified in the com.sun.cldc.i18n.j2me.Conv class. 5. Implement two classes for the character encoding. a. Put the classes in the com.sun.cldc.i18n.j2me package. Call the source files yourEncoding_Reader and yourEncoding_Writer. For example, ISO2022JP_Reader and ISO2022JP_Writer. Put the source files in your modules classes/com/sun/cldc/i18n/j2me subdirectory. b. Have the reader and writer extend the Gen_Reader and Gen_Writer classes of the com.sun.cldc.i18n.j2me package. c. Implement constructors for the reader and writer. The readers and writers constructors must provide the name of the encoder to their superclasses by calling super(encoding). For example, they might call super(ISO2022JP). Your classes do not need to extend any methods other than the constructor. 6. Add the new module to the build system. See the Build Guide for instructions.

212

Architecture and Design Guide December 2008

Changing the Default Screen Orientation


The default locale for the Java Wireless Client software is U.S. English (en-US). Therefore, the default screen presentation uses a left-to-right orientation. However, some languages, such as Hebrew and Arabic, are read from right to left. When localizing for these languages, the Sun Java Wireless Client software allows the screen display to be customized to use a right-to-left orientation.

Customizing the Screen Display


Left-to-right screen orientation is found in the system properties file, properties.xml. It is set using the system parameter microedition.locale, as shown in CODE EXAMPLE 20-1.
CODE EXAMPLE 20-1

Setting the Screen Orientation

<property Key="microedition.locale" Value="LTR"/>

The microedition.locale parameter sets the layout mode of the screen using one of the following values:

LTR - left-to-right presentation (the default) RTL - right-to-left presentation

Every language supported in the Java Wireless Client software is associated with one of these screen orientations. Therefore, during the porting process, the porting engineer should be sure to check that the layout mode matches the language being implemented. Changing the screen layout can be done as part of the build process, or during runtime using the JavaCall API. For example, the screen layout could be changed by the user via an interactive menu item that sets the screen to the desired layout. When the screen layout menu item is selected, the application sends CHANGE_LOCALE_EVENT to MIDP and the layout is changed. Both ways of changing the display are supported by the Java Wireless Client software.

Chapter 20

Porting the User Message Bundle Service

213

214

Architecture and Design Guide December 2008

21

Games
This chapter discusses the design and porting of the games subsystem of Java Wireless Client software. The games subsystem provides capabilities required by many arcade-style 2D games. The games subsystem implements the classes in the package javax.microedition.lcdui.game. The subsystem supports sprites (including animation, transformations, and collision detection), tiled backgrounds (including animated tiles), compositing of multiple visual layers, synchronized screen painting, and key polling and latching. The games subsystem interacts with the low-level graphics and image subsystem and the devices native APIs, as FIGURE 21-1 shows.
FIGURE 21-1

Interactions of Subsystems Games subsystem Low-level graphics and images subsystem Native platform APIs

Engineering and Device Requirements


Before you start to port the games service, you must meet the following requirements:

Be familiar with the material in the following documents:

MIDP 2.0 Specification, especially the graphics section.


Chapter 21 Games 215

The Java Virtual Machine Specification, Second Edition. The Java Programming Language (3rd Edition). KNI Specification, which is part of the CLDC Reference Implementations documentation. See http://java.sun.com/products/cldc/. Chapter 10. Low-level graphics capability of your platform MIDP 2.0 Display.flashBacklight method, and your devices backlight control APIs MIDP 2.0 Display.vibrate method, and your devices vibrator control APIs Low-level graphics and images subsystem High-level user interface subsystem (specifically, you must have already ported the display and canvas components)

Understand the following technologies:


Have already ported the following subsystems:


You must also complete your port of the CLDC component of the Java Wireless Client software stack.

Design
The games subsystem has the following design requirements and goals:

Maximize Code Reuse and Minimize Footprint Achieved by implementing the games package on top of the features available from the low-level graphics and images subsystem Performance Achieved by taking advantage of the low-level graphics and images subsystem, so optimizing that functionality also results in performance improvements in this subsystem Flexibility Encourage optimization for specific hardware capabilities during port time

The games subsystem has three components:


Sprites and tiled layers Visual elements for representing in-game objects Layer manager Handles the rendering of its layers Game canvas Extends the Canvas class with an off-screen graphics buffer that can be synchronously flushed to the display and the ability to poll for key status rather than receive events

216

Architecture and Design Guide December 2008

Sprites and Tiled Layers


The Sprite and TiledLayer classes are subclasses of Layer. The Layer class defines methods to position itself when it is rendered. A layer renders onto the Graphics object passed to it through the paint method. The layer is positioned with respect to the origin of this Graphics object. Both sprites and tiled layers use an Image object as the source for all rendering operations. The image holds every frame of the sprite or every tile for the tiled layer. The frames and tiles are indexed as described in the MIDP 2.0 Specification. For performance, the component caches the width and height of a frame or tile. It also caches arrays for the x coordinates of the frames or tiles and the corresponding y coordinates. The array indices correspond to the frames or tiles index numbers. See the MIDP 2.0 Specification for more information on index numbers. Sprites also have collision detection. Collisions occur when non-transparent pixels in a sprite touch another visual element: an image, tiled layer, or another sprite. Collision detection is implemented by querying for the transparency status of intersecting collision regions. If two non-transparent pixels intersect, a collision occurs. This is accomplished because the backing stores of images, tiled layers, and sprites are all images. Tiled layers can have animated tiles, as described in the MIDP 2.0 Specification. To support animated tiles, the component maintains an animated-to-static-tile array that maps the negative of an animation index to the individual tile currently being shown for the animation. For example, if the application developer supplies an animation index of -1 for a particular cell, the system displays the tile at position 1 in the animation-to-tile array.

Example Sprite
FIGURE 21-2 shows a source image for a sprite. The component holds the number of frames (16), the source frame height (10), the source frame width (16), and the arrays of x and y coordinates. Following is the array of x coordinates:

[0, 16, 32, 48, 0, 16, 32, 48, 0, 16, 32, 48, 0, 16, 32, 48]

Following is the array of y coordinates:


[0, 0, 0, 0, 10, 10, 10, 10, 20, 20, 20, 20, 30, 30, 30, 30]

Chapter 21

Games

217

FIGURE 21-2

Source Image for a Sprite 16 32 48

0 10 20 30

The application provides an array with the sequence of frames, such as this:
[0, 1, 2, 12, 13, 14, 8, 9, 10, 4, 5, 6, 3, 15, 11, 7]

Java Wireless Client software displays the frames in that order, as shown in FIGURE 21-3.
FIGURE 21-3

Example Animation Sequence

Example Tiled Layer


FIGURE 21-4 shows a source image for a set of tiles.
FIGURE 21-4

Source Image for a Set of Tiles 10 20 30

0 10

The component caches the number of tiles (8), the source frame height (10), the source frame width (10), and the arrays of x and y coordinates. Following is the array of x coordinates:
[0, 0, 10, 20, 30, 0, 10, 20, 30]

Following is the array of y coordinates:

218

Architecture and Design Guide December 2008

[0, 0, 0, 0, 0, 10, 10, 10, 10]

During a rendering operation, the grid location (x, y) containing i, is drawn using the following algorithm:

The static tile of index i, if i is positive. The current frame of the animated tile sequence -i, if i is negative. A tile of index 0 is treated as empty. Nothing is rendered for cell locations with this tile.

For example, assume the application specifies that an animated tile is needed, and the first tile of its animation is tile 5. For this, the component provides an animation index of -1, and the value (0, 5). Further assume that the application provides the following values for the tiled layers grid:
[ 0, 0, 1, 0, 1, 4, 1, 4, 4, 3, 4, 4, 0, 3, 4, 0, 0, 3,

-1, -1, -1, -1, -1, -1]

In this case, the tiled layer is rendered as shown in FIGURE 21-5.


FIGURE 21-5

Tiled Layer

Layer Manager Component


The LayerManager class manages the rendering of multiple layers. The layer manager has a view window, which is the region to be rendered, and only renders layers with coordinates in the view window. When the layer manager paints the screen, it follows these steps: 1. Gets the graphics object. 2. Sets the clipping region to the view window.

Chapter 21

Games

219

3. Renders the layers in the view window by calling the layers paint method with the graphics object.

Game Canvas Component


The GameCanvas component provides an off-screen buffer with synchronous repaints and the ability to poll for key events. The capabilities support applicationspecific game loops, in which applications can query the status of keys, advance the game state, and synchronously update the display during each iteration of the loop. The component implements the off-screen buffer as a mutable image and supplies it to applications through a Graphics object. Applications get the Graphics object by calling the getGraphics method. The component provides synchronous repaints by updating the screen only when the application flushes the Graphics object. The application can turn off key events when it creates a game canvas. In this case, the application polls for keys instead of having key events propagate to it.

Design Rationale, Notes, and Considerations


The games subsystem is implemented in the Java programming language for simplicity and portability. It interacts heavily with the low-level graphics and images subsystem. For example, all sprites, tiled layers, and layer managers render onto a Graphics object. Sources of sprite frames and tiled layer tiles are Image objects. A game canvas renders onto a Graphics object. Your port must efficiently use the components of the low-level graphics and image subsystem. When you make device-specific optimizations for the underlying Graphics and Image objects, maintain compatibility with the games subsystem.

Porting
Because Java Wireless Client softwares implementation of this subsystem is completely coded in the Java programming language, there are no native interfaces for game implementation. This simplifies implementation and allows for platformspecific optimization. Because the capabilities of devices vary drastically with respect to the functionality in this package (for example, sprites), a port must be individually optimized to take advantage of these capabilities.

220

Architecture and Design Guide December 2008

Porting GameCanvas
GameCanvas adds additional functionality to Canvas, particularly with respect to key polling and synchronous flushing. Neither of these features require additional native APIs and can be implemented entirely in the Java programming language. Depending on the port, it might be advantageous to replace some of the implementation with native code. This is a decision that must be made during the port, after evaluating the features that the device offers. Key polling can be implemented by short-circuiting all key events destined for Canvas (and its subclass GameCanvas) so that the key states are stored in a buffer in the platform code. GameCanvas.getKeyStates might then be implemented so that it reads and then clears the buffer. This avoids key events for Canvas being propagated through the usual event mechanism. Synchronous flushing is currently implemented using a MutableImage as the rendering buffer. If the platform provides a data structure that can be efficiently used as the destination of a javax.microedition.lcdui.Graphics object, then the buffer can be implemented using the data structure to avoid object creation and other overhead.

Porting Sprite and TiledLayer


Both classes are subclasses of Layer. However, Layer cannot be subclassed by the developer, so any port has some freedom in implementing these classes. Sprite and TiledLayer are very closely tied to the package javax.microedition.lcdui.Image. In its current implementation, the easiest way to speed the rendering performance of these classes is to optimize Graphics.drawRegion with any operation that quickly transfers pixels of image data from the source to the destination. However, to optimize the implementation for a specific device, you must ensure that the devices representation of Sprite and TiledLayer can easily use an Image as source. This for creation and rendering purposes and also to implement pixel-level collision detection. Collision detection can be implemented using a bounding box or at the individual pixel level. If the target device does not offer pixel-level detection, it might be possible to reuse parts of the code that perform rendering transformed regions of images to do transformed traversal of pixels within Sprite and TiledLayer. This again underlines the necessity to carefully design the relationship between the representation used for Image and Sprite and TiledLayer.

Chapter 21

Games

221

222

Architecture and Design Guide December 2008

Performance Notes
This document describes how to analyze and tune the performance of the Java Wireless Client software for the following aspects of performance:

Application startup time Runtime performance Memory footprint

Application Startup Time


Application startup is measured from the time a user starts an application to the time when the application finishes painting the first interactive screen. Users might perceive different application startup times for various reasons. For example, some applications present splash screens while they load resources and initialize themselves. The splash screen is interactive because it enables the user to exit the MIDlet. However, it does not give the user full access to the MIDlets functionality, so a user might not consider the MIDlet started at that point.

Measuring Startup Time


The Java Wireless Client software does not directly measure startup time. Instead, it uses the systems timer to generate timestamps at particular points during the startup process. In order to print the system time to the console at the points described below, build the system with the parameter MEASURE_STARTUP set to true in the following file: midp/src/configuration/configuration_xml/platform/constants.xml

Appendix A

Performance Notes

223

The following list describes the output. 1. Before the VM starts and MIDP is initialized. The output is: System Startup Time: Begin at systemTime 2. After a pre-installed MIDlet is launched, if the Java Wireless Client software uses a Java AMS. The output is Application Startup Time: Begin at systemTime. If your port uses the native AMS, add code to report this. The native AMS in the Java Wireless Client software does not include this code. 3. After the system paints the screen during a screen change event, if no prior screens were active. The output is Startup Time: End at systemTime. 4. When the system processes a MIDlets move to the foreground, after the system paints the content of the MIDlets displayable. The output is Startup Time: End at systemTime. 5. At the beginning of foreground and background switching. The output is: Switch To Background Time: Begin at systemTime Switch To Foreground Time: Begin at systemTime 6. At the end of foreground/background switching. The output is Startup Time: End at systemTime. System startup time is the interval between point 1 and either point 3 or point 4, whichever comes first. Application startup time is the interval between point 2 and either point 3 or point 4, whichever comes first.

Handling Startup Time Variance


Performance measurements vary from run to run, especially when measuring startup time. The differences in time can be caused by the following factors:

Low system timer resolution Unpredictable system activity, such as garbage collection (GC) Other background activity in the VM, such as MIDlets running in the background

224

Architecture and Design Guide December 2008

Averaging a number of measurements keeps you from thinking that an unusually short or long startup time is a typical interval. You could average in different ways, such as:

Launch a MIDlet a number of times (for example, ten) from the AMS and average the obtained times. Start the Java Wireless Client software some number of times (such as ten). During each run, launch a MIDlet some number of times. Average the values taken from one launch (such as the second) from each run.

The first method is suitable unless there are variations between starting the first MIDlet and starting subsequent ones. For example, if subsequent MIDlet starts cause a GC, it provides variation in startup times. The second method reduces this impact because the MIDlets associated with the chosen launch always start under similar conditions.

Starting an Application
This section focuses on application startup time. The Java Wireless Client software uses different procedures depending upon whether it is in single-tasking or multi-tasking mode. The following table describes the initial steps.
TABLE A-1 Step

Initial Steps in the Procedure for Starting a MIDlet


Multi-Tasking Mode

Single-Tasking Mode

0 1 2 3 4 5

Terminate the current VM (Java AMS only). Start the new VM with the MIDletSuiteLoader class. Initialize MIDP subsystems and services. Create and register the MIDlet instance. Start a new task with the class AppIsolateMIDletSuiteLoader. Initialize MIDP subsystems and services. Create and register the MIDlet instance.

Call the startApp method of the MIDlet. Call the startApp method of the MIDlet. Paint the MIDlets displayable. Paint the MIDlets displayable.

Note Steps 2 through 5 are the same in both releases.

Appendix A

Performance Notes

225

As implied by Step 0, the single-tasking mode with a native AMS does not have a current VM to terminate. However, Step 0 does not significantly affect application startup time. With either type of AMS, the time required to get through the initial steps of the initialization in single-tasking mode is about four times longer than in multi-tasking mode. Values of about 40 milliseconds compared with 10 milliseconds were seen on typical platforms. This is about five to ten percent of startup time for the simplest MIDlets. Times are approximate because many things affect startup time. For example, if a port with a native AMS does not have a running VM when the MIDlet is launched, Step 1 does not launch a task, but starts a virtual machine. This negatively impacts startup time for the first MIDlet launched. It does not impact other MIDlets because the Java Wireless Client software keeps executing a running VM even if it no longer has active MIDlets. It does not include Step 0. As another example, low memory can lengthen startup time. If memory is low, memory allocation can cause a GC, which dramatically lengthens startup time. Other system activity, such as the use of a just-in-time (JIT) compiler, can also affect startup time. See Optimizing the System for Improved Application Startup Time on page 227 for more information. Multitasking, then, has the following advantages and disadvantages for application startup time:

It does not require cycling the VM or reloading system classes. It has an AMS task running constantly, so shared resources are already loaded. Reloading shared resources can slow system startup. It has less memory for user applications, which can cause system activity such as a GC.

Optimizing a MIDlet for Improved Application Startup Time


As noted in Starting an Application on page 225, the first step or steps (through Step 1) of starting a simple application can take five to ten percent of a simple applications startup time. However, these same steps take a much smaller percentage of the time for a complex MIDlet with a lot of startup time initialization.

226

Architecture and Design Guide December 2008

Because the first steps take a small percentage of time, the following suggestions concern the steps that a MIDlet writer can take to minimize the time required for Step 3 through Step 5:

Minimize the number and size of startup classes. Step 3 and Step 4 create a MIDlets main classes. The system uses class verification for each non-ROMized class it loads. Class verification slows startup time for MIDlets that load a lot of classes or large classes at this time. To improve startup time, have a MIDlet load the minimum number of classes when it starts. Request only immediately required resources. Step 4 allocates and initializes MIDlet resources. Memory is one such resource and, as noted in Starting an Application on page 225, the multitasking environment makes less memory available to each MIDlet than an environment that runs only one MIDlet at a time. If memory is low, memory allocation can cause a GC, which dramatically lengthens startup time. To minimize this risk, request only the resources your MIDlet initially requires during MIDlet startup. Keep the initial displayable simple. Step 5 paints the content of a MIDlets displayable. The time required for painting depends on the complexity of the displayable. Covering the background and other large surfaces with small tile images, using many layers, and using many user-interface elements increases the time required to paint the screen. Simpler screens take less time to paint, which improves startup time.

Optimizing the System for Improved Application Startup Time


The following sections provide suggestions for optimizing the Java Wireless Client software to improve application startup time.

Minimizing the Static Initialization of System Classes


Step 2 and Step 3 of MIDlet startup cause the initialization of many system classes. They are usually ROMized, so they load quickly. However, the system calls the static initializer associated with each class that it loads, and that can be time consuming. Avoid creating long or resource intensive static initializers in classes requested at startup.

Appendix A

Performance Notes

227

Controlling the JIT Compiler and Ahead-of-Time Compilation


The Java Wireless Client software has a JIT compiler. Using this compiler is optional, but if you use it your runtime performance can be up to four times better than using the interpreter only. It is especially beneficial to MIDlets that do calculations for 2D or 3D graphics. Unfortunately, although the JIT compilers strategy is to compile long-running and often-called methods, it often compiles methods during startup that are only called once by the MIDlet or system. For these methods, compilation lengthens the MIDlets startup time without improving the MIDlets runtime performance. To minimize this problem, specify the startup methods that are not called again and are not performance critical as methods not to be processed by the JIT compiler. Before building, specify the methods with the DontCompile property in the midp/build/common/config/rom.config file as follows: DontCompile = methodName Specify that methods be precompiled if they meet the following criteria:

You call performance-critical methods during startup You call some methods often You have very large methods

Precompiling at build time is called Ahead of Time Compilation (AOTC). AOTC gives you the benefits of compilation without using the JIT compiler during startup. Before building, specify AOTC for appropriate methods with the Precompile property in the midp/build/common/config/rom.config file as follows: Precompile = methodName Both the DontCompile and Precompile properties can have values that contain the * wild card. For example, the following is a short way to indicate that none of the methods of a particular class are to be compiled:
DontCompile = FullClassName.*

See the Ahead-of-Time Compilation Support and ROMizer chapters in the CLDC-HI Architecture Guide for further information about these mechanisms.

Giving the VM Hints


Using a static list of methods to control the JIT compiler improves startup performance, but completely disabling the JIT compiler helps even more. Starting an application with the JIT compiler disabled can be up to 50 percent faster.

228

Architecture and Design Guide December 2008

The Java Wireless Client software has an optimization that disables the JIT compiler during application startup. It reenables the JIT compiler after an applications startup phase is finished. The optimization is designed to be more general than just disabling the JIT compiler. The optimization simply notifies the VM of the beginning and the ending of an applications startup phase. The CLDC HotSpot Implementation can adjust any internal VM parameters during the application startup period. However, the current adjustment only disables the JIT compiler. The challenge in creating the VM-hinting optimization is determining the end of the application startup phase. The optimization uses the moment when a MIDlet instance is created and registered to the system. This is after startup Step 3. The decision makes system behavior less efficient than ending at Step 5 but that step cannot be used because it is not reached by MIDlets that are designed to run in the background. Those MIDlets have no displayable. Similarly, startup Step 4 cannot be used because some MIDlets, especially those used for benchmarks, never leave the startApp method. The VM hinting is built into the Java Wireless Client software. You cannot turn it on or off using build time or run time options. However, you can use its internal API to give the VM hints about any additional startup that you add. For example, if you implement an optional package that needs initialization when a MIDlet starts, you can add a hint for your optional package in the same way that the product provides hints for its core startup activity. The Java programming language API to use for giving the VM hints is part of the com.sun.midp.main.MIDletSuiteLoader class interface:
static public void vmBeginStartUp(SecurityToken token, int midletIsolateId) static public void vmEndStartUp(SecurityToken token, int midletIsolateId)

Surround your initialization with calls to these methods. You can add any number of VM hinting intervals, but you must make sure that each interval has both a beginning and an ending. You can nest intervals. The vmBeginStartUp and vmEndStartUp methods call the native API provided by the CLDC HotSpot Implementation:
void JVM_SetHint(int task_id, int hint, int param)

You can also use this native API to give the VM hints if you have implemented additional initialization in both the Java programming language and native code.

Appendix A

Performance Notes

229

Disabling the Class Verifier


The Java Wireless Client software must verify a MIDlets non-ROMized classes. Verification at startup can be lengthy. The system can disable the class verifier to remove this delay. To make it possible for the system to disable the class verifier, set the following options before building the system:

Set the CLDC HotSpot Implementation build option ENABLE_VERIFY_ONLY to true. Set the Java Wireless Client software build option USE_VERIFY_ONCE to true.

Disabling class verification introduces the possibility of creating security holes in the system. To ensure that the system is secure, the following additional requirements must be met.

The system must verify the MIDlet suites classes during its installation. The system must confirm that the classes have not been changed since installation.

This optimization is possible because the Java Wireless Client software starts only installed MIDlets. The system verifies all classes in a MIDlet suites JAR file when it installs the MIDlet, and aborts the installation if any class fails. If the classes are successfully verified, the system evaluates the hash value of the JAR file and saves it to secure persistent storage. When the system starts the MIDlet, the system checks for the hash value. If the hash is present, and is the same as JAR files hash value, the system disables the class verifier when it starts the MIDlet. Otherwise, the system uses the class verifier in the usual way. When the USE_VERIFY_ONCE and ENABLE_VERIFY_ONLY build options are set, the Java Wireless Client software automatically fulfills the first requirement by verifying the MIDlets classes at install time. However, you must take special precautions to ensure that the hash value is stored securely. If the hash value is not stored securely, an attacker could modify the JAR file, recompute the hash value, and overwrite the previously stored hash value. This would effectively bypass class verification and open a large security hole.

Caching Images
MIDlets can load image resources, such as logos and splash screens, during startup or at runtime. It can load different image resources at different times. Depending on the characteristics of the target device, it might be faster to cache images on the device and get them from the cache at startup, instead of from the JAR file. The image caching optimization is controlled by the USE_IMAGE_CACHE build option, which is set to true by default.

230

Architecture and Design Guide December 2008

Loading an image from the JAR file requires two steps. The system must read the image data and decompress it. If the image is in PNG format, which is likely because PNG is the only format for which the MIDP 2.1 Specification guarantees support, the system must convert it to the platforms native format. As an alternative, when USE_IMAGE_CACHE is set to true, the Java Wireless Client software caches all image resources in a JAR file to the MIDlet suites persistent storage. The system caches the images in the platforms native image format. The porting team can determine which of these methods is faster, because it depends on the speed from which persistent storage can be read. It might be faster to load a small portion of data from the JAR file.

Caching JAR File Entries


The Java Wireless Client software provides caching for the entries (although not the content) of non-image resources in the JAR file. For example, it can cache the entries associated with byte codes. The cache stores any accessed entries of the JAR file, as well as the entries traversed during an access request. The system then gets information from the cache, such as the entrys location in the JAR file, to improve the speed of executing subsequent requests. Using an entrys location is somewhat faster than searching for the entry from the beginning of the JAR file. The optimization is best for MIDlets that load many resources. Follow these steps to enable caching of JAR file entries: 1. Set the CLDC Hotspot Implementation build option ENABLE_JAR_ENTRY_CACHE to true. It is false by default. 2. Build the system. 3. Use the runtime option +CacheJarFileHandles. The procedure for using a runtime option depends on your AMS as follows:

Java AMS - Put the runtime option at the front of the command line you use to start the main system binary, runMIDlet. For example:
runMIDlet +CacheJarFileHandles internal com.sun.midp.appmanager.MVMManager

Appendix A

Performance Notes

231

Native AMS - Provide the runtime option in your ported code as an argument to the JVM_ParseOneArg function as shown in the following example:
char *argv[] = { "+CacheJarFileHandles", 0 }; { ... JVM_ParseOneArg(1, argv); ... }

If you have other runtime options for the VM, call JVM_ParseOneArg() in a loop.

Runtime Performance
This section covers the following aspects of improving runtime performance:

Performance metrics Profiling the System Runtime Optimizations

Performance Metrics
Evaluating runtime performance requires metrics (benchmarks) that are measurable, persistent, and comparable. The following benchmarks, each of which reports a numeric value that you can compare across your Java Wireless Client software optimizations, are widely accepted:

MorphMark JBenchmark JBenchmark2 Amark v1.3 TaylorBench eembcBM

232

Architecture and Design Guide December 2008

Profiling the System


The most effective way to improve runtime performance is to optimize the systems bottlenecks. You find bottlenecks in the Java Wireless Client software by using the built-in Java platform profiler. The following steps describe how to enable and run the profiler. 1. Set the CLDC Hotspot Implementation build option ENABLE_WTK_PROFILER to true. 2. Set the Java Wireless Client software build option USE_JAVA_PROFILER to true. 3. Build the system. 4. Specify the runtime option +UseExactProfiler when you start the Java Wireless Client software. Provide this parameter as you did the +CacheJarFileHandles parameter. Enabling the profiler affects the execution speed of the Java Wireless Client software but, as much as possible, the profiler excludes the time spent for its own activity. The profiler automatically dumps the data it collects when a task exits or when the Java Wireless Client software exits.

Runtime Optimizations
Many optimizations are already built into the Java Wireless Client software. For even better performance, you can apply the techniques in Optimizing the System for Improved Application Startup Time on page 227 as runtime optimizations. You can also apply the following platform-specific optimizations to your port of the Record Management System (RMS).

Caching
Modern mobile devices often use flash memory to store persistent data. Flash memory typically provides fast read operations but slower write operations. To compensate for the slower write operations, Java Wireless Client software writecaching is optimized. The system caches in memory the data to be written to the RMS and only writes it when the memory allotted to the cache is full or when an RMS storage area is closing. If a power failure or abnormal system termination occurs, unflushed data in the RMS cache might be lost, but the RMS does not become inconsistent.

Appendix A

Performance Notes

233

To control the size of the RMS write cache, set the value of the RMS_CACHE_LIMIT constant in the file constants.xml in the directory midp/src/configuration/configuration_xml/platform. The Java Wireless Client software does not have a read cache because the read speed of the caches memory is typically similar to the read speed of the storage memory. Read caching provides no benefit in this case and can even hurt performance due to cache maintenance overhead. If your device has a slower read speed for storage memory than for RAM, consider implementing read caching in your port. Note that although the Java Wireless Client software does not have a read cache, it can read from the write cache when necessary. If the system or a MIDlet tries to read a record that is still in the write cache, it receives the data in the write cache, not the older data in storage memory.

Indexing
The RMS API provides a facility for MIDlets to retrieve records using record identifiers (recordIds). The com.sun.midp.rms.RecordStoreIndex class maintains the offsets of each record identifier and free block. The class has an implementation that maintains a linear index and an implementation that maintains a tree index. The two index types store data differently and have different performance characteristics. The linear index stores the offsets in RAM in a linear data structure that provides O(n) worst-case search time for the needed offset. The tree index stores the offsets in separate RMS storage, which is partly loaded into RAM during runtime. The tree index uses a B-tree structure that improves the worst-case search time to O(log(n)), but is more complex to maintain. If your device has slow write operations for its storage memory, the overhead to support the tree structure can exceed the benefit of a faster search. Choose which index type to use based on the performance characteristics of your device. Specify your choice with the USE_RMS_TREE_INDEX build option. Set its value to true to use the tree index, and to false to use the linear index.

Buffering
An efficient way to use flash memory and other block devices is to read and write large blocks of data. Larger blocks of data require fewer read and write operations to process a given volume of data. To increase the amount of data available during a write operation (that is, to provide a larger data block), the Java Wireless Client software uses internal write buffering when it flushes its cache.

234

Architecture and Design Guide December 2008

The Java Wireless Client software does not buffer RMS read operations. The reasons are the same as those for not providing read caching. As with read caching, if your device reads from storage memory more slowly than it reads from RAM, consider implementing read buffering in your port.

Memory Footprint
You can measure the following two types of memory footprint:

Static footprint - The amount of memory the device needs to hold the program code. The device might store the code on disk, on a flash card, in ROM, or in some other location. Dynamic footprint - The amount of memory the Java Wireless Client software uses when it runs. The footprint varies depending on the products workload. The products Java runtime environment has a dynamic footprint, as does its C/C++ component. Both dynamic footprints consist of memory used for their code (the static footprint affects this number), their heaps, and their stacks.

Measuring Footprint
Measuring static and dynamic footprints are platform-specific activities. Java Wireless Client software does not provide measurement tools, but this section describes techniques you can use. The static footprint of the Java Wireless Client software with a Java AMS is the file size of the system binary runMIDlet. System utilities, such as the Linux platform size utility provide detailed information. The static footprint of the Java Wireless Client software with a native AMS is the sum of the sizes of all of the system binaries. Static footprint includes other application resources too, such as the systems PNG files. The size of those resources change less frequently as you do your port, than the size of the binary. Therefore, you probably need only check the size of your binaries as you improve your port. The dynamic footprint, because it depends on the activity level of the Java Wireless Client software, is not a single number. To find a representative dynamic footprint, follow these steps.

Appendix A

Performance Notes

235

1. Decide the activity level to measure. For example, you might measure the dynamic footprint when the system is running but no MIDlet suites have been started, or when the system is running a particular MIDlet suite, such as a Hello World! MIDlet. 2. Use system tools to measure the footprint at different times during the chosen activity level. System tools include the task manager on Windows platforms and a monitor of RAM footprints on Linux platforms. 3. Use the measurements to compute an average value or find the maximum value.

Minimizing Static and Dynamic Footprint


Because devices have limited resources, this section shows you how to minimize the static and dynamic footprint of the Java Wireless Client software without hurting startup or runtime performance. See the book Java Platform Performance: Strategies and Tactics (Addison Wesley, 2000) for more information on performance issues in general, and the RAM footprint of a Java application in particular. Although the book covers the Java SE platform, many of the ideas also apply to the Java ME platform. Two optimizations, code sharing of system classes and image sharing, are built into the Java Wireless Client software. Sharing the Java platform system classes among all tasks decreases the dynamic footprint. Instead of the footprint including the size of the system classes times the number of tasks, the footprint only includes the size of the system classes once. The software does not share users classes. The Java Wireless Client software also shares system image resources. The tasks use the images to render user interface (UI) elements. For example, all skin images are shared. The following sections describe optimizations that you can make.

Heap Capacity for the Java Platform


The VM allocates a heap for Java platform objects. That heap is part of the Java Wireless Client softwares common native heap. The default size of the Java platform heap is between one megabyte and four megabytes. If multitasking is not enabled, the default size is one megabyte minimum and maximum. The JVM_SetHeapLimit API is provided to implement a user-administered space in the Java platform heap. When this feature is on, the Java platform heap size is not adjustable. However, it is possible to set build flags to turn off the JVM_SetHeapLimit API, in which case the heap size is dynamically adjustable.
236 Architecture and Design Guide December 2008

When the JVM_SetHeapLimit API is disabled, you can control the minimum and maximum sizes of the Java platform heap by using the following runtime options:

=HeapMinSize =HeapCapacitySize

Provide these parameters as you did the +CacheJarFileHandles parameter. The Java Wireless Client software passes your values to its VM. For example, to set the initial size of the Java platforms heap to four megabytes and the maximum size to 16 megabytes, set the options as follows:

=HeapMin4M =HeapCapacity16M

To help determine the required capacity of the Java platform heap, track the heaps size with the following APIs:.

public long java.lang.System.freeMemory() public long java.lang.System.totalMemory()

Have your code request a full GC before calling these methods so that you get precise values. Because getting the memory size this way is an expensive and performance-impacting activity, consider using the following strategy to estimate the size requirements of the Java platform heap:

Start the Java Wireless Client software with a =HeapCapacitySize option that enables the application to start without an error. Exit the Java Wireless Client software, and restart it with a smaller Size. Repeat the previous step until you receive an error indicating that you are out of memory.

Minimizing the Space Used by AOT and JIT Compilation


The size of a compiled method can be up to eight times bigger than the size of the methods original bytecode. The following steps describe how to minimize the footprint of compiled code. 1. Select the most time-intensive, frequently-used methods for AOTC and prohibit JIT compilation for large methods that are not performance critical and methods called only once (such as static initializers). Base your selections on collected profiler data or general reasoning. See Controlling the JIT Compiler and Ahead-of-Time Compilation on page 228 for instructions on using the profiler.

Appendix A

Performance Notes

237

2. Use the Dontcompile and Precompile settings to implement your choices. See Controlling the JIT Compiler and Ahead-of-Time Compilation on page 228 for instructions. Selecting methods to not compile and to precompile also improves performance in another way. It stops the JIT compiler from creating and re-creating compiled code that the system throws away when memory is low. The JIT compiler uses memory from the Java platform heap to compile methods. When memory is low, the system often throws away the least-used code created by the JIT compiler. As part of the deletion, the system reverts the methods to their uncompiled bytecodes. The JIT compiler might select those methods for recompilation when more memory becomes available.

Minimizing Full Garbage Collections at Startup


The Java Wireless Client software has a generational mark-sweep-compact garbage collector that automatically reclaims memory from unused objects. It runs quickly across the new generation segment of the Java platform heap. However, when the new generation segment is full, the garbage collector reclaims memory by doing a full GC. It also increases the size of the Java platform heap at this time, unless the heap has reached its maximum size. Because a full GC creates a noticeable pause, which negatively impacts performance, it is best to minimize your chances of needing one during startup. To do this, start the Java Wireless Client software with a reasonable minimum heap size. See the CLDC Hotspot Implementation Virtual Machine White Paper for details.

Summary
You can improve performance of your Java Wireless Client software in many ways. To improve application startup time, use the following suggestions when you create MIDlets:

Minimize the number and size of the classes you create during startup. Request only immediately required resources during initialization. Keep your initial displayable simple.

Use the following suggestions to improve performance in your system:

Minimize the static initialization of the system classes used during application startup. Control the behavior of the JIT compiler.

238

Architecture and Design Guide December 2008

Use AOTC as necessary. Give the VM hints regarding any additional startup blocks you add to the system. Disable class verification for installed MIDlets. Cache image resources if this is appropriate for your device. Cache JAR file entries for faster resource loading. Use proper caching, buffering, and indexing for RMS operations. Increase memory in the Java platform heap to decrease the number of GCs required.

Appendix A

Performance Notes

239

240

Architecture and Design Guide December 2008

Glossary
API Application Programming Interface. A set of classes used by programmers to write applications, which provide standard methods and interfaces and eliminate the need for programmers to reinvent commonly used code. Application Management Service. The system functionality that completes tasks such as installing applications, updating applications, and switching foregrounds. The screen that lists all of the installed applications. The user gets to this screen by pressing the Apps soft key on the home screen. The application list uses text color to show which applications are running. It also provides a system menu that enables the user to perform application management tasks on the highlighted application. An application state in which the application does not receive events from its input stream and its displayable is not rendered to the screen. Connected Device Configuration. A Java ME platform configuration for devices, it requires a minimum of 2 megabytes of memory and a network connection that is always on. Connected Limited Device Configuration. A Java ME platform configuration for devices with less than 512 kilobytes of RAM and an intermittent (limited) network connection, it uses a stripped-down Java virtual machine called the KVM, as well as several minimalist Java platform APIs for application services. Defines the minimum Java runtime environment (for example, the combination of a Java virtual machine and a core set of Java platform APIs) for a family of Java ME platform devices. The application state in which the application is rendered to the device display and the input stream is passed to it. Changing which application is in the foreground by shifting the focus from one application to another. Generic Connection Framework. A part of CLDC, it improves network connectivity for wireless devices.
Glossary 241

AMS

Application list

Background CDC

CLDC

Configuration

Foreground Foreground switching GCF

Home screen HTTP

The main screen of the application manager. This is the screen the user sees after they exit an application. HyperText Transfer Protocol. The most commonly used Internet protocol, based on TCP/IP, which is used to fetch documents and other hypertext objects from remote hosts. Secure HyperText Transfer Protocol. A protocol for transferring encrypted hypertext data using Secure Socket Layer (SSL) technology. Java Application Descriptor file. A file provided in a MIDlet suite that contains attributes used by application management software (AMS) to manage the MIDlets life cycle, as well as other application-specific attributes used by the MIDlet suite itself. Java Archive file. A platform-independent file format that aggregates many files into one. Multiple applications written in the Java programming language and their required components (.class files, images, sounds, and other resource files) can be bundled in a JAR file and provided as part of a MIDlet suite.

HTTPS JAD file

JAR file

Java Community ProcessTM (JCPTM) program

Java Community Process program. An open organization of international developers and licensees who develop and revise Java platform specifications, reference implementations, and technology compatibility kits using a formal submission and approval process. Java Platform, Micro Edition. A group of specifications and technologies that pertain to running the Java platform on small devices, such as cell phones, pagers, PDAs, and set-top boxes. More specifically, the Java ME platform consists of a configuration (such as CLDC or CDC) and a profile (such as MIDP or Personal Basis Profile) tailored to a specific class of device. A proposal for developing new Java platform technology, which is reviewed, developed, and finalized into a formal specification by the JCP program. A software execution engine that safely and compatibly executes the byte codes in Java class files on a microprocessor. A Java virtual machine designed to run in small devices, such as cell phones and pagers. The CLDC configuration is designed to run in a KVM. Liquid Crystal Display. A common kind of screen display often used in small devices. Liquid Crystal Display User Interface. A user interface toolkit for interacting with LCD screens in small devices. More generally, a shorthand way of referring to the MIDP user interface APIs. An application written for MIDP.

Java ME platform

Java Specification Request (JSR) Java Virtual Machine KVM LCD LCDUI

MIDlet

242

Architecture and Design Guide December 2008

MIDlet suite

A way of packaging one or more midlets for easy distribution and use. Each MIDlet suite contains a Java application descriptor file (.jad), which lists the class names and files names for each MIDlet, and a Java Archive file (.jar), which contains the class files and resource files for each MIDlet. Mobile Information Device Profile. A specification for a Java ME platform profile, running on top of a CLDC configuration, which provides APIs for application life cycle, user interface, networking, and persistent storage in small devices. A technique used to complicate code by making it harder to understand when it is de-compiled. Obfuscation makes it harder to reverse-engineer applications and therefore, steal them. A set of Java ME platform APIs that provides additional functionality by extending the runtime capabilities of an existing configuration and profile. Portable Network Graphics. An image format commonly used with MIDP that can be compressed, transmitted, and stored without losing image quality. Taking a resource, such as the foreground, from another application. Due to limited memory and processing power on small devices, the process of verifying Java technology classes is split into two parts. The first part is preverification and done off-device using the preverify tool. The second part, which is verification, is done on the device at runtime. A set of APIs added to a configuration to support specific uses of a mobile device. Along with its underlying configuration, a profile defines a complete and self-contained application environment. A mechanism for providing services, data, or both to a mobile device over a network. The list of inbound connections, across which entities can push data, maintained by the Java Wireless Client software. Each item in the list contains the URL (protocol, host, and port) for the connection, the entity permitted to push data through the connection, and the application that receives the connection. Remote Method Invocation. A feature of Java SE technology that enables Java technology objects running in one virtual machine to seamlessly invoke objects running in another virtual machine. Record Management System. A simple record-oriented database that enables a MIDlet to persistently store information and retrieve it later. MIDlets can also use the RMS to share data. Short Message Service. A protocol allowing transmission of short text-based messages over a wireless network.

MIDP

Obfuscation

Optional Package PNG Preemption Preverification

Profile

Provisioning Push Registry

RMI

RMS

SMS

Glossary

243

SOAP

Simple Object Access Protocol. An XML-based protocol that allows objects of any type to communicate in a distributed environment, it is most commonly used to develop web services. Secure Sockets Layer. A protocol for transmitting data over the Internet using encryption and authentication, including the use of digital certificates and both public and private keys. A set of Java programming language tests developed specifically for the wireless marketplace, providing targeted, standardized testing for CLDC and MIDP on small and handheld devices. Single Virtual Machine. A mode of the Java Wireless Client software, it can run only one MIDlet at a time. At the platform level, each separate application that runs within a single Java virtual machine is called a task. The API used to instantiate each task is a stripped-down version of the Isolate API defined in JSR 121. See the CLDC HotSpot Implementation Architecture Guide for more information. Transmission Control Protocol/Internet Protocol. A fundamental Internet protocol that provides for reliable delivery of streams of data from one host to another. Wireless Application Environment. It provides an application framework for small devices, by leveraging other technologies such as WAP, WTP, and WSP. Wireless Application Protocol. A protocol for transmitting data between a server and a client (such as a cell phone) over a wireless network. WAP in the wireless world is analogous to HTTP in the World Wide Web. Wireless Messaging API. A set of classes for sending and receiving Short Message Service messages. The button the user presses to end a task. On a real device this is the End key. On Windows it is the End key and sometimes the power key on the phone skin.

SSL

Sun Java Device Test Suite

SVM task

TCP/IP

WAE WAP

WMA (x) button

244

Architecture and Design Guide December 2008

Index

A
Access module, 208 Adaptive User Interface Technology, 115 customization, 117 porting high-level UI, 115 adding a new locale porting steps, 210 Alert sound types, 108 alpha encoding adding alpha values, 103 palette, 103 alpha transparency, 103 ALPHA_LEVEL constant, 93 alpha-blending, 103 API module for Logging and Tracing service, 34 APP_DIR constant, 159 application management subsystem components of, 146 Application Management System (AMS), 145, 159 Application Manager, 147 application startup time (performance tuning), 223 ARGB data, 103 ARGB format, 102 audio channels, limited number, 108 AUI technology (Adaptive User Interface Technology), 115 Auto MIDlet Invocation subsystem porting issues, 172 porting strategies, 172 user interaction, 174 using networking protocols, 172

AutoTester, 147

B
backlight duration, 110 ash rate, 110 backlighting, 108 Behavior module, 208 blanket permission, 183 building Java Wireless Client software, 10

C
chameleon class package, 116 com.sun.midp.chameleon, 116 com.sun.midp.chameleon.layers, 116 com.sun.midp.chameleon.skins, 116 channels reporting mechanism, 37 channels, adding, 37 circle, mathematical denition of, 96 classes Graphics, 81 Image, 103 javax.microedition.lcdui.Graphics, 93 javax.microedition.lcdui.Image, 101 LayerManager, 219 RecordStore, 43 Sprite, 217 TiledLayer, 217 collision detection, 217 Command-line MIDlet Runner, 147 Command-line MIDlet Suite Lister, 148

245

Command-line MIDlet Suite Remover, 148 compacting source, 24 compositing, 104 CONFIG_SUBDIR constant, 159 Configuration.getProperty method, 23 congurator, 23 to 31 description of, 23 design of, 24 external interactions with, 23 input for constants, 29 XML format, 27 XML-formatted les, 27 constant_class element, 30 constants ALPHA_LEVEL, 93 APP_DIR, 159 CONFIG_SUBDIR, 159 DISPLAY_NUM_COLOR, 93 ERASE_COLOR, 93 IMAGE_DEPTH, 93 Low-Level Graphics table of, 93 MOTION_SUPPORTED, 93 POINTER_SUPPORTED, 93 REPEAT_SUPPORTED, 93 constants output, 27 createImage, 105

rectangles, 95 rectangles with rounded corners, 100 drawRect method, 95

E
ellipse drawing, 96 mathematical denition for, 96 emulator, porting with, 11 ERASE_COLOR constant, 93 event service event locking, 137 MIDP event structure, 136 normal (master) mode, 138 porting, 133 slave mode, 140 eXtensible Stylesheet Language (XSL) les, 31 External Push Listener, 170 External RMS API, 43

F
le system, PCSL library, 62 le system, POSIX, 62 les midpIndicators.h, 109 Options.gmk, 112 storagePosix.c, 159 lling arcs, 96 rectangles, 95 rectangles with rounded corners, 100 fillRect method, 95 xed resource management (multitasking), 189 font mapping, 107 font variables, 107

D
data types, sizes of, 18 database les, 44 DatagramConnection, 193 Decoder, 87 error types, 88 implementing, 88 device backlighting, 108 Discovery Application, 147 display illumination, 108 Display Manager, 181 Display.flashBacklight, 108 Display.vibrate method, 110 DISPLAY_DEPTH, 93 DISPLAY_NUM_COLOR constant, 93 drawArc method, 96, 97 drawing arcs, 96 lines, 94
246 Architecture and Design Guide December 2008

G
Game Canvas component, 220 Games subsystem components of, 216 porting GameCanvas, 221 porting Sprite, 221 porting TiledLayer, 221 Generic Connection Framework (GCF), 193, 194 generic tunneling mechanism for TCP-based protocols, 197

Graphical Installer, 147 Graphics class, 81, 93 drawing arcs, 96 drawing lines, 94 drawing rectangles, 95 drawing rectangles with rounded corners, 100 lling arcs, 96 lling rectangles, 95 lling rectangles with rounded corners, 100 graphics context, 83 graphics context component, 84 graphics porting layer, 82, 91 graphics primitives drawing methods, 81 library of drawing primitives, 82 graphics rendering component, 81 Graphics.drawImage method, 101 Graphics.drawRegion method, 101

index les, 44 Installer, 181 Internal API Protection subsystem restricting access to classes, 178 Internal Push Listener, 169 dened, 169 internationalization, 207

J
Java Wireless Client software, 1 porting architecture, 7 resource limitations, 18 javax.microedition.lcdui.Image class, 101, 103 JIT compiler, 228 JTWI permission levels, 184

L
LayerManager class, 219 locale-specic content component porting, 210 locking, event, 137 Logging and Tracing service API module, 34 channels, 37 code removal at compile time, 36 Logging and Tracing subsystem adding channels, 37 logging, denition of, 33, 36 Low-Level Graphics and Images subsystem components of, 79 constants checklist, 92 design requirements, 80 external interactions, 80, 81, 86, 87 Image component, 101 image rendering, 104 image transformation, 104 improving performance, 91 network indicator, 112 optimizing performance, 114 porting checklist for Image component, 105 porting checklist for primitive graphics, 92 porting steps for Image component, 105 porting strategies for primitive graphics, 112 porting verication, 113 primitive graphics, 92 vibration, 110
Index 247

H
handles (PCSL networking), 65 host development environment, 17 HTTP 1.1 persistent connections, 198 HTTP protocol (porting), 197 HTTP proxy servers, 197 HTTP tunneling, 197 HttpConnection protocol, 193 HTTPS protocol, porting, 198 HttpsConnection protocol, 193

I
Image class, 103 Image component, 84 image formats, 102 image rendering, 90 Image storage component, 89 Image.getGraphics, 101 IMAGE_DEPTH constant, 93 images, transforming, 104 immutable images creating, 86 decoder, 87 implementing decoders, 88 storage formats, 101, 102 inbound connection notications, listening for, 173

low-level graphics porting groups, 90

N
naming conventions of graphics drawing methods, 91 native bitmap format, 89 Native Resource Management for Multitasking, 189 native stack size, conguring, 18 network connection states, 170 network indicator, 112 networking protocols DatagramConnection, 193 HttpConnection, 193 HttpsConnection, 193 SecureSocketConnection, 193 ServerSocketConnection, 193 SocketConnection, 193 networking, PCSL library, 64 networking, porting, 193 normal mode (events), 138

M
malloc(), 60 master mode (events), 138 mathematical denitions circle, 96 ellipse, 96 memory management porting requirements, 215 memory manager design, 80, 168, 216 memory, PCSL library, 59 message buffering, 173 methods drawArc, 96, 97 drawRect, 95 fillRect, 95 MIDlet Auto Invocation subsystem components of, 169 goals for, 168 MIDlet Suite Loader, 181 MIDlet Suite Storage, 181 MIDlet suites performing authorized actions, 182 MIDlets optimizing startup time, 226 performance tuning, 223 tuning startup time, 223 MIDP 2.0, security model, 181 MIDP permission checking system, 188 MIDP permissions levels, 183 MIDP Runtime Environment, 147 midpIndicators.h le, 109 MOTION_SUPPORTED constant, 93 multiple MIDlets, running, 174 multitasking xed resource management, 189 open resource policy, 190 porting resource issues, 191 resource management, 189 mutable images creating, 87 dened, 101 storage formats, 102

O
one shot permission, 183 open resource policy (multitasking), 190 Options.gmk le, 112

P
palette alpha encoding, 103 PCSL, 57 BSD networking, 68 le system library, 62 memory allocation library, 59 network notication, 69 networking library, 64 print library, 58 socket-over-serial networking, 69 performance tuning, 223 to 239 application startup time, 223 giving VM hints, 228 permission management subsystem adding new permissions, 185 dependent systems, 181 systems dependent on, 181 permissions, adding, 185 Persistent Application Storage, 147 PLTE chunk, 103 PNG information, 103

248

Architecture and Design Guide December 2008

PNG transparency, 103 porting, 103 POINTER_SUPPOERTED constant, 93 porting event processing service, 133 graphics using PutPixel technology, 75 HTTP protocol, 197 HTTPS protocol, 198 networking, 193 networking subsystem, 195 PCSL, 57 user message bundle service, 210 porting points, 7 porting SATSA optional packages, 223 porting strategy, 9 porting, heap-based implementation, 61 porting, malloc-based implementation, 60 POSIX le system, 62 Preprocessor component, 85 primitive graphics routines, 92 primordial stack, 18 print, PCSL library, 58 properties adding new, 28 properties output, 27 Public Keystore Manager, 148 push protocol, 172 PushRegistry, 169 PutPixel technology, 75 to 77 building, 76 porting, 75 screen buffer, 75 testing, 76 tuning, 76

renderRegion, 104 REPEAT_SUPPORTEDconstant, 93 resource limitations, 18 ROMizer, 24 runtime information, reporting, 34 runtime memory, conserving, 18 runtime security security token, 179 runtime security service design requirements, 177

S
Sandbox component of RMS, 43 secure random data for SSL, 199 SecureSocketConnection, 193 Security and Trust Services API porting of, 223 security checks, avoiding multiple, 179 security token, 179 server socket, 199 ServerSocketConnection, 193 session permission, 183 slave mode (events), 140 SocketConnection, 193 Sprite class, 217 SSL implementation, 199 startup time (measuring), 223 storagePosix.c le, 159 strategy, porting, 9 System.getProperty method, 23

T
TiledLayer class, 217 tracing, denition of, 33, 36 transforming, 104 transparency, 103 tRNS chunk, 103

R
record management subsystem functions of, 41 porting strategies, 45 record management system (RMS), 41 design requirements, 42 RecordStore class, 43 renderer component, 90 rendering images, 103 rendering operation, 83

U
User Message Bundle, 207 user message bundle service porting, 210

Index

249

V
vibration support, 111

W
WAP gateway, using a, 197

250

Architecture and Design Guide December 2008