9. Decisions
• Built from the DNA of the web
• HTML CSS widgets
• JavaScript APIs
• Tracking HTML 5 standards
10. webOS Architecture
Applications
App Services
Services UI System Manager
Cloud
Window Manager Mojo Framework
Window Server Application
Manager
NPAPI
Browser
Palm Bus
Wireless Media
DocViewers
OS Services OS Middleware
Kernel/User Space
Boundary
Linux Kernel FileSystem TCP/IP
Bootie Drivers
13. Scene Lifecycle
initialize Find Scene
Push This Scene
(constructor
setup Start
Transition
ready
readytoactivate
activate End
Transition
Push New Scene
deactivate Start Pop This Scene
Transition
cleanup
Scene Framework
14. Widgets
• Model View Controller
• View (HTML)
• Assistant (JavaScript)
• Model (optional)
17. JavaScript
ActivateAssistant.prototype.setup = function() {
//turn destroyPlanet function into an event handler
this.destroyPlanetHandler =
this.destroyPlanet.bindAsEventListener(this);
//attach handler to the button with tap events
this.controller.listen("myDestroyButton",
Mojo.Event.tap,
this.destroyPlanetHandler);
}
ActivateAssistant.prototype.destroyPlanet = function(event) {
console.log("destroying the planet with event " +
event);
};
23. PDK: Plug-in Development Kit
• C/C++
• Posix, OpenGL, SDL, PDL
• When you need speed and low level access
• Full screen or hybrid
• Come back tomorrow!
29. Initial HTML
<!DOCTYPE html>
<html>
<head>
<title>DestroyWorld</title>
<script src="/usr/palm/frameworks/mojo/mojo.js" type="text/javascript" x-mojo-
version="1"></script>
<!-- application stylesheet should come in after the one loaded by the framework -->
<link href="stylesheets/destroyworld.css" media="screen" rel="stylesheet" type="text/
css">
</head>
</html>
34. Activate-assistant.js
ActivateAssistant.prototype.setup = function() {
//turn destroyPlanet function into an event handler
this.destroyPlanetHandler =
this.destroyPlanet.bindAsEventListener(this);
//attach handler to the button with tap events
this.controller.listen("myDestroyButton",
Mojo.Event.tap, this.destroyPlanetHandler);
};
ActivateAssistant.prototype.destroyPlanet = function(event) {
console.log("destroying the planet with event " + event);
};
35. The webOS Emulator
• VirtualBox (version xxx required)
• x86 build of webOS
• Most things identical
• Not all hardware features supported (camera,
multitouch)
• Simulate events
36. Navigating the Emulator
• Esc = back gesture
• Left / Right = flip between apps
• Home = minimize / maximize card
• End = bring up launcher
• Mouse = single touch events
• F5 – F9 = accelerometer event simulation
38. Emulator Host Mode
• Embedded web server
• Use your desktop browser
• Good for inspecting HTML
• ssh -p 5522 -L 5581:localhost:8080 root@localhost
• http://localhost:5581/Apps
41. Ares
• Visual IDE and GUI builder: WYSIWYG
• Runs in the browser
• Makes the same apps as the command-line SDK
• Works with local emulator, debugging, logging
• Works with real devices
• Makes most coding tasks much faster
42. Ares vs. Mojo
• Slightly different style of coding
• Mojo widgets contained in lightweight wrappers
• Not all widgets are supported (more coming)
• Code is more concise
48. Access an XML Webservice
var url = "http://myserver.com/webservice?results=all";
var request = new Ajax.Request(url, {
method: 'get',
evalJSON: 'false',
onCreate: function(){console.info('******* onCreate happened')},
onLoading: function(){console.info('******* onLoading happened')},
onLoaded: function(){console.info('******* onLoaded happened')},
onSuccess: function(){console.info('******* onComplete happened')},
onComplete: this.gotResults.bind(this),
onFailure: this.failure.bind(this)
});
49. Parse Response with DOM & XPath
StartAssistant.prototype.gotResults = function(event){
var xmlstring = event.responseText;
var doc = (new DOMParser()).parseFromString(xmlstring, "text/xml");
// Use xpath to parse xml object
var items = document.evaluate("/root/item", doc, null,
XPathResult.ANY_TYPE, null);
var item = nodes.iterateNext();
while (section) {
console.log("id = " + item.attributes['id'].nodeValue);
item = items.iterateNext();
}
}
50. Use the Camera
//launch the camera view
this.controller.stageController.pushScene(
{
appId : 'com.palm.app.camera',
name: 'capture'
},
{
sublaunch : true,
filename : '/media/internal/testpicture.jpg'
}
);
//the activate function on your scene
activate: function(event) {
if(event != undefined) {
//the camera returned
console.log("json = " + Object.toJSON(event));
console.log("filename of the photo = " + event.filename);
}
}
51. Use the Accelerometer (Tilt Sensor)
• Orientation events
• Shake Events
• Raw events
52. Orientation Events
• Pitch & roll in degrees
• Numeric codes for different orientations
• 0 = face up
• 1 = face down
• 2 = up / normal portrait
• 3 = down / reverse portrait
• 4 = left / landscape, left side down
• 5 = right / landscape, right side down
56. Raw Accelerometer Events
• Raw x/y/z acceleration values
• Default 4Hz (four times per second)
• Option for 30Hz (good for games)
• 'acceleration' property
59. Mojo Cookies
• Store simple values
• 4k of storage
• Good for preferences, version numbers, etc.
• Stored as a single JSON value in the Depot
60. Cookies
var SCROLL_MODE_KEY = “SCROLL_MODE_KEY”;
...
//set the current mode
var scrollModeCookie = new Mojo.Model.Cookie(SCROLL_MODE_KEY);
scrollModeCookie.put(scrollMode);
//retrieve it later
var scrollModeCookie = new Mojo.Model.Cookie(SCROLL_MODE_KEY);
console.log(“mode = “ + scrollModeCookie.get());
61. Mojo Depot
• Simple object store for JSON
• No schemas or SQL queries
• Up to 1MB of storage
• > 1MB available in media storage
• Object -> SQL translation underneath
• Not as efficient as true HTML database
• Uses callbacks extensively
62. Create
var db = new Mojo.Depot(
{'name':‘DestroyWorldDB'},
function(code) {
console.log(“open db succeed”);
},
function(code) {
console.log("open db failed");
}
);
console.log("created db : " + db);
63. Store
var db = new Mojo.Depot(
{ 'name' : 'DestroyWorldDB' },
function(code) {
console.log("open db succeeded " + db);
var value = { 'target':"world", 'action':"destroy"};
db.add("object1", value,
function(){console.log("saved okay");},
function(){console.log("save failed");}
);
},
function(code) {console.log("open db failed");}
);
64. Retrieve
var db = new Mojo.Depot(
{ 'name' : 'DestroyWorldDB' },
var db = new Mojo.Depot(
function(code) {
{ 'name' : 'DestroyWorldDB' },
console.log("open db succeeded " + db);
function(code) { 'target':"world", 'action':"destroy"};
var value = {
console.log("open db succeeded " + db);
db.add("object1", value,
db.get("object1",
function(){console.log("saved okay");},
function(obj){
function(){console.log("save failed");}
); console.log("got object. target = " + obj.target);
}, },
function(code) {console.log("open db failed");}
function(){console.log("get failed");}
); );
},
function(code) {console.log("open db failed");}
);
65. HTML 5 Database
• Database object from HTML 5
spec, but not storage object
• True SQL database
• Transactional
• Databases associated with
applications
• Private, no inter-app sharing
• Up to 1MB of storage
• > 1MB available in media storage
• Work is ongoing to match the
spec
71. International Apps
• Translating is strongly encouraged, not required
• Set prices for each country
• Metadata for each language (title, description,
screenshots, etc.)
• Auto-generate prices for each currency zone
73. Palm Hot Apps Promotion
• Total payout: One Million Dollars
• Earn a bonus based on
• Free: downloads
• Paid: total revenue
• Feb 1 – June 30
• Still plenty of time to win!
• Leader board updated daily
• http://PalmHotApps.com/
goal: by the end of this class you will be able to make a webos application and be ready to submit it to the store
prereqs: nothing beyond basic programming skills and knowledge of HTML. If you can build an interactive website you can build a webOS app.
first a quick bit about myself and how i came to palm.
i've been a java programmer for close to 15 years, ever since the first betas in 95. i wrote swing hacks for oreilly and worked on the javafx and java store projects at Sun. I really care about user interfaces.
For a long time I was negative about the web as a user interface technology. And when I say &#x2018;web&#x2019; I really mean HTML, JavaScript, and CSS. They are slow and extremely limited. They are great for text but not much else. Anything interesting in the web space has to be done on the server side.
Well I was wrong.. or rather, the web technology stack has advanced tremendously since I had last looked at it. Last november I happen to meet my friends Ben and Dion at the OreDev conference in Sweden. Yes, it&#x2019;s true, I had to travel to Sweden to meet up with people from my own timezone. So I went to their presentation and was amazed by how far web technology has come in just a few years. AJAX was the beginning of making the web truly interactive and expressive. New javascript engines are making it almost as fast as the Java Virtual Machine and native code. New APIs are arriving to fill in the gaps. Things like real 2D bitmap canvas. Animated SVG for vector graphics. WebGL for 3D. HTML 5 storage. Web Workers for threads.
The platform is really moving forward, and best of all it's open. Not controlled by any one vendor with an agenda. That really spoke to me. finally it is possible to create great user experiences with completely open technology... and on mobile devices, no less. So that's why I joined Palm... to be a part of the open mobile revolution.
What is the webOS?
The webOS is Palm's mobile operating system. It was designed from the ground up to be a mobile operating system for devices with a touch screen and a physical keyboard. It can scale to different screen sizes and hardware capabilities while presenting a uniform platform to you, the software developer.
devices and market
We currently have the Pre and the Pixi. Their hardware is roughly equivalent, with the Pre having a larger screen, more storage, and slightly faster CPU & GPU. They both support the exact same software, however, and it's very easy to adjust to the screen sizes.
technology decisions and direction
The webOS was designed from the beginning to be built from the DNA of the web. The SDK is HTML, CSS, and JavaScript, which are the core languages of the web. You can use any Javascript libraries that you want, such as Prototype, JQuery, or MooTools. We provide Javascript apis for the core operating system functions like access to the camera, address book, location, and storage. We are tracking the HTML 5 standard and plan to support more of it as the standard becomes complete.
webos architecture
linux base
The core of the webOS is a linux kernel with a posix filesystem and the typical posix APIs. It is linux underneath so we a true multi-threading, power management, unix filesystem, etc. All of the things you expect from a real linux OS. Generally these are hidden from the app developer, though you can access many of the posix APIs with the PDK, subject to access restrictions.
window manager
Above the Linux core is the window manager, called Luna, which controls access to the screen and provides the core drawing functions through OpenGL and WebKit.
javascript apis
Above Luna are javascript apis for all of the device features. Things like camera and location are hardware services written in C and exported to the javascript layer through simple apis.
The actual applications are written in HTML, JavaScript, and CSS. Javascript manipulates the underlying webpage DOM to create the graphics you see on screen. All of the apps you see in the OS are written like this. In fact, the SDK actually provides the source to much of the built in apps so you can see how they are constructed. All of the widgets are provided by the Mojo APIs, which are javascript as well. In the SDK you can see all of the core css and images used to draw the wigets on screen. Use of Mojo is not required, but it is recommended because it lets you use a common look and feel, and implements all of the mobile specific features like touch events and infinite scrolling lists.
application architecture
difference between a webos app and a web app. no webserver. everything is local. you implement state changes and program logic in javascript locally. you don't call back to a server somewhere.
cards, stages, and scenes
the webos uses the 'card' as the core ui metaphor. with a few exceptions, every app is shown as a card. the user switches between apps much as you would deal a deck of cards, flipping from one card to another. this is a very tangable metaphor that everyone can grasp very quickly.
from an application point of view you have stages and scenes. a stage is a card. a scene is a view within that card. you only see one scene at a time. if this was a webpage then the stage would be the browser window or tab, and the scene would be a page on your site. the user can navigate from scene to scene, or page to page. some apps actually have more than one stage, meaning they have more than one card visible. a good example of this is the email app. there is one card for viewing your mail. it has multiple scenes: one for the list of inboxes, one for the list of mails in your inbox, and one for the mail you are currently useing. the mail app also has secondary stages for when you compose an email. in this case it shows a full separate card so that you can write an email but still switch back to the inbox to read another email before you are done.
I&#x2019;m not going to cover it in this session, but there is also another kind of stage called a dashboard. This is a little indicator at the bottom of the screen that lets you know you have a message or alert or some other notification. This can be expanded into a full dashboard, which is a wide but short window across the bottom that gives the user more info and the ability to take action. Usually this will open up the full app that created the notification, or it may provide the user with other controls, such as the music player which lets you pause or switch tracks.
MVC design for widgets and structure
apis and widgets
the mojo toolkit provides all of the standard widgets for things like menus, buttons, text input, and of course the all important scrolling list control. most apps will reuse these existing widgets.
The widgets are represented as DIVs in your markup. You can also customize the look of the widget using CSS. There are a bunch of prefab CSS classes for the standard widgets with different variations. You can override these styles with your own CSS, of course.
here's an example of some buttons. Notice how they both have the css class &#x2018;palm-button&#x2019; but the second one also has the class &#x2018;negative&#x2019;.
Here&#x2019;s what that view looks like without adding any more code or CSS.
You then wire up the widgets using JavaScript. This code will turn the &#x2018;destroyPlanet&#x2019; function into an event listener with the bindAsEventListener function. Then it attaches the listener to the button using the &#x2018;listen&#x2019; function on the scene controller.
The stage has a full lifecycle for a reason. This lets you know when resources are needed and when they are no longer need. This lets you clean up resources at the right time and avoid memory leaks. always, always remove event listeners in the &#x2018;cleanup&#x2019; function
there are mojo apis for various services provided by the OS. this includes access to device features like the camera, and application services like the address book and calendar.
Here&#x2019;s a simple API request. We ask the application manager service (as shown here in red) to open the application &#x2018;com.palm.app.email&#x2019; and send it this block of parameters. This will open a new email message with the specified recipient.
Threading: there is no programmer accessible threading. everything happens in the gui thread. However, there are apis to handle things that would typically be done in a background thread, such as downloading and uploading files. For example, here's how to upload a file to twitpic.com.
This code calls the downloadManager service with the upload method (yes, I know it&#x2019;s confusing to call it the download manager in this case). You pass in the parameters for the url you want to post to, the file to upload, and the extra http parameters. You can also pass in some callback functions for when the post succeeds or fails. This is how you can do something that would normally require a thread. The API does it for you and calls you back when it&#x2019;s done.
You can also use this API to download a file and process XML & JSON.
We are monitoring the HTML 5 standard and are looking at the WebWorkers spec for true background processing. However, for a lot of the tasks you&#x2019;d want to do our APIs eliminate the need for direct threading.
Most device access is handled through a similar APIs. You call a service with some parameters and a callback function. Some APIs have their own GUI, such as the camera. So instead of making a service request you simply tell the stage to navigate to the scene for that GUI. This is called pushing.
Here&#x2019;s an example of opening up the camera scene. We push to the com.palm.app.camera service with a parameter to say the name of the photo we want to write to.
I&#x2019;m not going to cover the PDK today, but I thought I would mention it. When designing websites sometimes there are things you can&#x2019;t do using pure web technologies. These are usually things that require maximum speed or direct hardware access, such as 3D graphics. On the web you would use browser plugins for these things. We have the same thing in the webOS called the plugin development kit, or PDK. This lets you write plugins for your apps which use native C and C++ code. We give you a standard linux/posix environment with access to OpenGL, SDL for input, and our PDL API to access Palm specific APIs.
PDK apps can be either pure PDK running as full screen, such as most of our 3D games, or hybrid apps where you mix some native code with an HTML based Mojo app.
I&#x2019;m not going to cover the PDK here today because this is an intro day, but come back tomorrow for some great indepth sessions on the PDK.
We do have an eclipse plugin [right?] and our Ares visual tool, but I'm going to just use the core SDK with command line tools to show you what's really going on. It's sort of like in math class where your teacher taught you how to add and subtract before showing you how to use the calculator to do it faster. The command line tools also make it very easy to automate your development workflow using ant files, hudson, and other build systems.
commandline tools
our command line tools are written in [java? python? bash?] so they should run everywhere. The whole SDK is designed to be platform independent and usable from open source tools, which is why we chose VirtualBox as our emulator.
First run the command line tool palm-generate. It uses templates. The &#x2018;new_app&#x2019; template will create the full directory structure needed for a basic app. Let's make an app. I&#x2019;m tired of &#x2018;Hello World&#x2019; apps so let&#x2019;s make the most epic app ever: &#x2018;Destroy World&#x2019; It will let you destroy the planet with the click of a button.
palm-generate -t new_app DestroyWorld
let's take a look at the dir structure [open a file browser window showing the dir structure]
Everything is laid out in a nice clean directory structure. there's a place for images, stylesheets, html, and your javascript.
[show the contents of the appinfo.json file]
appinfo.json is the metadata about your project. you'll want to edit it first to change the title and package id of your app.
[open initial index.html]
this is the top of the 'real' page. it defines the css and javascript you want to import by default.
now let&#x2019;s create our first scene. I&#x2019;m going to call this scene &#x2018;Activate&#x2019;
palm-generate -t new_scene -p "name=Activate" DestroyWorld
This will create the html and javascript files for our scene.
Now in order to make the scene show up we need to push it. So in our stage assistant we&#x2019;ll call pushScene with the name of the scene: &#x2018;Activate&#x2019;
Now let&#x2019;s open the view for our scene
This is the html file for our scene. i'm going to add two buttons
[paste in code for two buttons, one to activate, one to destroy]
Again, notice that the second button has the &#x2018;negative&#x2019; css class set.
now we will package it up and test it in the emulator.
first, package the app with the command
palm-package DestroyWorld
now start the emulator
now install the app with the command
palm-install com.palm.dts.destroyworld_1.0.0_all.ipk
now that it's in the emulator we can run it and see that it works. cool.
now let's edit the actual javascript code for this page to make the button do something.
[open up scene assistant]
every scene has a view, the html file, and an assistant, which is the javascript code. let's attach an event handler to our destroy button.
[paste in code for the button. code should print &#x2018;destroying the world ...&#x2019;]
package and test it again in the emulator
The webOS emulator is an instance of the open source project VirtualBox. It's an x86 build of our whole OS, so it really is very close to a real device except for the different hardware. Not all hardware features are supported, such as the camera. For some hardware like GPS you can simulate events using command line tools. This comes in very handy when building unit tests for your software.
[a note on virtual box: you must have version xxx]
these are the primary shortcut key&#x2019;s you&#x2019;ll want to know:
left and right to switch between apps
escape = &#x2018;back gesture&#x2019;
In addition to the key strokes for simple accelerometer events you can also simulate some radio features from the command line. For example you can fake an incoming phone call like this. And you can fake a GPS fix like this.
You can also use the luna-send command to control the GPS Auto Drive feature. This lets you use a fake GPS route out of a csv file. It&#x2019;s good for simulating the full GPS experience. Even if you have a real device to test on this can be useful for unit tests of edge cases.
As of 1.4.1 we added a mini webserver to the emulator. This lets you browse your apps from another webbrowser over an SSH tunnel. This is great for debugging. Just create a tunnel and then open our desktop browser to this page.
get a log of what your app is doing
[type in palm-log -f com.palm.dts.destroyworld]
There is a log file for each app. The &#x2018;palm-log&#x2019; command is equivalent to the &#x2018;tail&#x2019; command in Unix. You tell it which app to view the log for. It also supports the -f argument to follow, just like tail. I usually run this command in an extra terminal window and keep it running during development. It makes it easy to print debugging information.
Ares is our new visual IDE and gui builder. It lets you build webOS apps with a drag and drop gui builder. It&#x2019;s entirely webbased but uses the real emulator locally on your computer. It can even deploy straight to your USB connected phone. It really makes coding webOS apps easier and faster.
There are a few differences between Ares and regular Mojo apps. Ares wraps the mojo widgets in lightweight containers and handles a lot of the boilerplate code for you. You can drop down to regular Mojo APIs if you want to, which sometimes you have to do for the widgets that Ares hasn&#x2019;t wrapped yet.
The projects are stored on Palm&#x2019;s servers. You can download the source, or download the packaged up app, which is how the emulator works.
Now let&#x2019;s look at an example of Ares
open ares, create a simple one stage application with a header and the same &#x2018;activate&#x2019; and &#x2018;destroy&#x2019; buttons. make the destroy button have the negative class.
change orientation to show how stuff resizes automatically
run the app in the preview
show property sheet, add event handler to the button which prints to the log.
show the logging, undo/redo, jslint.
run the app in the emulator
use the &#x2018;email&#x2019; non visual component to create a new message when the activate button is pressed
In this session we are going to give you an overview of advanced APIs, then run through some specific examples to show you how they work and the overall API patterns.
The webOS has lots of APIs for all sorts of things so I&#x2019;ve divided them into four sections. First is direct monitoring of the hardware. Pretty much every piece of hardware in the phones has an API for it, such as the accelerometer and the GPS radio. Next are platform services. This are services apis for things that aren&#x2019;t really hardware but let you request features from the operating system. This is stuff like the current state of the network, power settings, and direct embedding of video streams.
Next are application services. This are simply APIs provided to your app to interact with the user&#x2019;s data on the device, with the appropriate privacy safeguards.
Finally we have application actions. These are apis that let you request another application to do something for you, usually by opening that application in a particular state. For example, with the Email API you don&#x2019;t directly send an email. Instead you ask the email app to open up a new message with the recipient and subject you provide.
Network services are super easy to access because the webOS was built on the web. If you want to talk to an XML webservice just do an AJAX request and give it a callback.
You can parse the response into an XML document using the DOMParser and then do XPath queries on the result. This is a great way to loop through webservice responses. And of course you can do the same with JSON as well.
Camera access is slightly different. The camera has an entire custom scene dedicated to taking pictures, so instead of calling an API with a callback function, you just have to push to the special camera scene and then watch for an event containing a filename when your scene is activated again. When you do this the camera viewer will take over the screen until the user is done taking a picture.
Every Palm device has a tilt sensor built into it, called an accelerometer. It doesn&#x2019;t actually measure tilting. Instead it measure acceleration in three dimensions relative to gravity. Through some clever math you can determine the orientation of the device. Since orientation is the most common thing you&#x2019;d want to do with an accelerometer we&#x2019;ve already done the math for you and given you a simple API to access it.
Just listen for orientation events. The event has a numeric code for the different possible positions along with the pitch and roll expressed in degrees
You can get these events by listening for the &#x2018;orientationchange&#x2019; event on the document.
Some apps use shaking as a specific gesture to trigger some behavior. To support this we created a shake recognizer which will send you events.
Again, just listen for the &#x2018;shaking&#x2019; event with a callback.
If you really want the raw acceleration events you can get that two. These are the raw x,y, and z values from the chip. Once you have these you can do whatever you want with them, like make a tilt sensitive racing game. The default refresh rate is four times per second but there&#x2019;s an option for a full 30hz event, which is great for games.
Again, just listen to the right property for events.
There are three kinds of storage: Cookies, the Mojo Depo, and the HTML5 record database. Which one to use depends on your needs.
Mojo Cookies just like normal web cookies. They hold small amounts of state and are limited to about 4K of storage.
To use them just create a cookie object for your key then get and set the value.
Mojo Depot is the next level of storage. It&#x2019;s an object store for JSON objects. It doesn&#x2019;t have any schemas or SQL, so it&#x2019;s very flexible but not as fast as a real SQL database would be. It can have up to 1MB of storage by default, and you can get more by storing the objects in the media storage partition. Underneath it&#x2019;s doing Object to SQL translation, which is why it&#x2019;s not as efficient as the HTML database. The API uses callbacks extensively to ensure proper asynchronous and safe access.
You can create and open a Depot database with an instance of the Mojo.Depot object. Pass in a JSON object with some parameters, including the name of your database. Then provide two callbacks, one if it succeeds and one if it fails.
To store something first open the database, then in the callback store your JSON object with the &#x2018;add&#x2019; method. this method takes the object to be saved and two more callbacks.
To retrieve objects do the same thing. Once your database is open call the &#x2018;get&#x2019; method with the key you used to save it. The callback will have the object as it&#x2019;s argument, and then you can pick it apart.
I&#x2019;m not going to go into detail on this. Basically it&#x2019;s a true SQL database store with transactional access through callbacks. You have to know SQL to use it, but it&#x2019;s the fastest. We are doing work to follow the HTML 5 spec and improve performance. Expect improvements in future releases of webOS.
app catalog
rules and structure
submission process
There is a fifty dollar fee to submit your app into the on device catalog. These apps go through the full review process, which currently takes about three business days. [verify]. This is the standard way most people distribute apps.
You can also distribute apps purely through the web feeds. These apps will not be listed in the on device catalog, but if a user clicks on a webpage link to the app it will come up in the catalog so they can buy it. This lets you do your own marketing for the app. There is no cost for these and they are not reviewed by Palm [verify]
The beta feed is free. Publish your app this way if you are just testing the app.
Open Source apps do not cost anything to submit in the main catalog if they are free. [verify]
All apps are submitted through our online portal at developer.palm.com.
Here you can manage all of your apps, submit new ones,
conclusion and roadmap
extras:
sources of graphics and icons
tools to use: cssedit, jedit, netbeans & eclipse