Professional Documents
Culture Documents
Sun Java Wireless Client Software 2.2 Java Platform, Micro Edition
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
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
13
17
iii
18
19 19 20 20 20
The DEFAULT_TOTAL_SPACE Property The STORAGE_SUITE_LIMIT Property Networking Resource Limitations Graphics Resource Limitations Other Resources 4. 21 23 21 21
Modifying Properties
28 28
Adding Properties 29
Constants
Modifying Constants
29 29 31 33 34
Adding Constants
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
37
Assertions 6.
41
Design Overview
43
44
54
Porting malloc-Based Implementations Porting the Heap-Based Implementation PCSL File System Interface PCSL Networking Library Handles and Contexts 62 64 65
60 61
66
Contents
69
Encoding for Non-English Resource Names 9. PutPixel Technology Porting Building Testing Tuning 10. 75 76 76 76 79 75
74
81 81 82
Design Rationale, Notes, and Considerations Graphics Context Component Detailed Design Image Component 83 84 85 83
89
vi
91 92
Porting Checklist for Primitive Graphics Drawing Graphics Primitives 93 101 101
105
105 105
String and Font Drawing and Accessing Group Alert Sound Group 108 108 108 109 109
Vibration Control Methods Vibration Porting Interface Vibration Support Network Indicator Porting Strategies Porting Issues 113 113 112 112 111
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
133
Setting the MAX_EVENTS Constant Types of Event Systems Normal Mode Slave Mode 138 138
138
viii
AMS Functionality
146 149
152
153 154
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 Customizing the AMS Things to Consider AMS UI Implementation Configuration Examples 160 161 162 162
Default Application Manager Custom Application Manager 15. MIDlet Auto Invocation Design 168 169 170 167
164 165
Design Overview
171
Protocols
Contents
ix
173
MIDlet Concurrency
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
Design Rationale, Notes, and Considerations Policy Configuration Implementations New Permissions
184
184 185
185 185
New Domains
189 190
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
Decoder-Encoder Component
209
Contents
xi
Changing the Default Screen Orientation Customizing the Screen Display 21. Games 215 213
213
215
Porting GameCanvas
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
230 231
xii
Runtime Performance
Performance Metrics
Measuring Footprint
Minimizing Static and Dynamic Footprint Heap Capacity for the Java Platform
Minimizing Full Garbage Collections at Startup Summary Glossary Index 238 241
245
Contents
xiii
xiv
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
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
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
97
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
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
3 4 48
Java Wireless Client Software Subsystems and Libraries Native File Library Prefix Examples 55 67
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
225
xvii
xviii
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
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-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
xx
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.
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
xxii
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.
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
xxiv
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
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.
Preface
xxv
xxvi
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.
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.
Note In
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.
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.
Chapter 1
Software Overview
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
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
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
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
Application (MIDlet)
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.
FIGURE 1-4
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
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
Graphical display
User interaction
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
10
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.
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
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
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.
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.
14
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
Chapter 3
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.
18
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.
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.
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
19
20
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
21
22
401
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
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.
24
FIGURE 4-1
Configurator Work Flow for Constants and Properties Property output files:
properties_static_data.c internal.config system.config Configurator merges the input into a single XML file, then generates output files Constant output files:
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 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
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
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
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
28
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
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
4. Add a new constant element to the appropriate constant_class element of your constants input file. For example:
CODE EXAMPLE 4-3
<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
Chapter 4
31
32
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
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.
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
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.
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
35
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
... // 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
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
The existing Java Wireless Client software code uses the Logging Service in this manner in both the Java platform layer and native layer.
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
... <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
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
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
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
39
40
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
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
The following sections describe the function and design of the components in FIGURE 6-1.
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.
Database Implementation
The database (the record store) component manages the storage of record stores and records. It has the following requirements:
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
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.
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
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.
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
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
Chapter 7
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
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
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
49
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 timer queue for master mode Timezone information Miscellaneous services provided by the VM (current time, current isolate ID, thread wait and signal)
demos/
50
events/
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
51
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
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
53
secure_random
Functions that provide unpredictable random data. Each implementation is device specific.
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.
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
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
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
55
56
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:
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.
58
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.
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
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.
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.
These functions have generic implementations based on pcsl_mem_malloc and pcsl_mem_free. They do not require any porting.
Chapter 8
PCSL
61
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
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
64
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.
Chapter 8
PCSL
65
66
FIGURE 8-1
JavaCall Implementation
WinSock Implementation
MIDP
MIDP
MIDP
MIDP
MIDP
pcsl_network.h
pcsl_network.h
SoS JavaCall
WinSock
pcsl_network_na.h
BSD Generic
pcsl_serial_linux
JavaCall Platform
Win32 Platform
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
Implementation
Chapter 8
PCSL
67
TABLE 8-1
Implementation
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
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.
70
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
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
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:
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
74
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
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
10
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
79
External Interactions
The low-level graphics and images service subsystem interacts with the following Java Wireless Client software subsystems:
High-level UI subsystem
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
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)
Chapter 10
81
FIGURE 10-2
public native void drawLine(int x1, int y1, int x2, int y2);
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.
82
Functions That Update Property Values and Functions Providing Data Translate translate
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
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
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.
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
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
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
85
Java platform:
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:
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.
86
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:
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
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)
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
Manages (allocates and deallocates) memory for storing images. Provides access to pointers that point to the following data:
Synchronizes a backing store for mutable images with a Graphics context. This is optional and depends on the design of the graphics context.
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
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
public native void drawLine(int x1, int y1, int x2, int y2);
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
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
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.
IS_DOUBLE_BUFFERED
92
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
Chapter 10
93
FIGURE 10-7
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
94
Chapter 10
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
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
FIGURE 10-12
-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
97
FIGURE 10-13
Boxed Ellipse
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
-120o
98
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
-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
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
99
100
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.
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
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:
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
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
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
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
8. Render regions of images. Render regions of immutable and mutable images with alpha blending. The implementation must pass the following tests:
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.
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
107
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.
108
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.
Chapter 10
109
/** * 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.
110
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);
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
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.
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
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
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
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
11
Design
AUI Technology software is implemented in the following Java programming language class packages:
javax.microedition.lcdui.* com.sun.midp.chameleon.*
Chapter 11
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
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.
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.
Chapter 11
117
118
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.
Chapter 11
119
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
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
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
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
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 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
123
124
12
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
125
FIGURE 12-1
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
FIGURE 12-2 shows the high-level GUI components and the components on which they depend.
FIGURE 12-2
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
Date Editor
Item
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
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
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
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
1. Java Wireless Client software includes versions of runMidlet that work on the Linux operating system and the Microsoft Windows operating system.
130
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
131
132
13
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
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
FIGURE 13-1
Native events
4
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
135
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.
136
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:
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:
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
137
Normal Mode
In normal mode, the main processing loop resides within the VM.
138
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
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
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
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
Initialization
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
141
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
Chapter 13
143
144
14
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
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
TABLE 14-1
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 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.
Chapter 14
147
TABLE 14-2
Additional Functionality
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.
FIGURE 14-1 shows the interactions of some of the components described in TABLE 14-1 and TABLE 14-2.
FIGURE 14-1
Discovery Application
Uninstaller
MIDP Runtime Environment Retrieve MIDlet Remove suite Get and set MIDlet suite information
148
systems.
TABLE 14-3 System
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
Push
Authenticates and authorizes signed applications for Java platform installers Performs the following installation services for native and Java platform installers:
Chapter 14
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.
150
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
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
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
151
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
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.
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
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
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
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
154
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.
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.)
156
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
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
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.
Note The APP_DIR and CONFIG_DIR constants are used only for non-JavaCall
ports.
158
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
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):
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
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
161
FIGURE 14-2
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
162
FIGURE 14-4
Chapter 14
163
For information on these build options and how to set them, see the Build Guide.
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
FIGURE 14-6
Chapter 14
165
166
15
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
167
The MIDlet auto invocation subsystem interacts with the subsystems and services listed in TABLE 15-1.
TABLE 15-1
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.
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
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).
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
170
FIGURE 15-1
Checked in MIDlet closes the port Checked out User denies permission to launch MIDlet Source does not match filter Source matches filter
Received event
Chapter 15
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
It must have separate channels or ports. For example, do not choose the comm protocol, because there is only one serial port.
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
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.
174
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
175
176
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
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.
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
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.
Chapter 16
Runtime Security
179
180
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.
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.
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
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
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
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
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
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.
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
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
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.
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
18
Refer to the Multitasking Guide for more information about multitasking and how to set the resource policy at build time.
Chapter 18
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.
190
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
191
192
19
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
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
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.
194
The set of Java classes in this area use the common features listed in TABLE 19-2.
TABLE 19-2 Feature
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.
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.
Chapter 19
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
Chapter 19
197
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 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
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
199
Protocol & (Scheme) Multimedia Message Service (mms) Bluetooth Serial Port Profile (btspp)
Parent Class
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
TABLE 19-3
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.midp.io.j2me.apdu .Protocol
com.sun.midp.io.j2me.jcrm i.Protocol
Chapter 19
201
TABLE 19-3
Parent Class
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()
202
TABLE 19-3
Protocol & (Scheme) Serversock et Protocol (serversoc ket) Secure Socket Layer (ssl)
com.sun.midp.io.j2me.ssl. Protocol
com.sun.kvem.io.j2me.ssl openPrim() .Protocol close() read() write() setSocketOption() com.sun.kvem.io.j2me.dat openPrim() agram.Protocol send() receive() close()
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
com.sun.kvem.netmon.obex ObexMsgReceiver
Chapter 19
203
TABLE 19-4
Lime Package
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 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
com.sun.kvem.netmon.http HttpMsgReceiver
204
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
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
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
20
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
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
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
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.
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.
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
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.
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.
210
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.
Chapter 20
211
4. Add the new module to the build system. See the Build Guide for instructions.
212
The microedition.locale parameter sets the layout mode of the screen using one of the following values:
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
213
214
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
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)
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
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
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]
Chapter 21
Games
217
FIGURE 21-2
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
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]
218
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,
Tiled Layer
Chapter 21
Games
219
3. Renders the layers in the view window by calling the layers paint method with the graphics object.
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
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.
Chapter 21
Games
221
222
Performance Notes
This document describes how to analyze and tune the performance of the Java Wireless Client software for the following aspects of performance:
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.
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
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
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.
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.
226
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.
Appendix A
Performance Notes
227
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.
228
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
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
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.
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
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:
232
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
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.
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:.
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.
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.
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.
Minimize the static initialization of the system classes used during application startup. Control the behavior of the JIT compiler.
238
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
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
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.
JAR file
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
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
Profile
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
SVM task
TCP/IP
WAE WAP
244
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
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
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
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