Application Lifecycle: Overview

Application Manager

The Application Manager controls application lifetime and execution. This is the component that is responsible for maintaining the simple application task model that users expect on a phone. The application manager starts and stops applications as appropriate, ensures that the current running application controls the main display, maintains a running list of applications, places applications in the background, and prevents multiple launches of a single application.

The Application Manager is initiated at system start-up and provides the following services:

  • Application launching mechanism and management of application lifecycle.
  • Routing of launch requests to the existing instance (if the application is already running).
  • Coordination of the "main UI app"—retires the current application when a new one is launched, and launches a default when needed.
  • May also provide default behavior for certain important system events (i.e., hard key handling, clamshell open/close).

The Application Manager will run in its own process. Applications will run in their own processes and control their own UI. This simple mapping of applications to processes provides a secure, stable model for application execution. To maximize utility on small screen form factors, we will preserve the standard Palm OS behavior of having one main UI application at a time, with that application having drawing control of the main panel of the screen (exclusive of status bars, etc.) When the user runs a new application, the system will generally ask the current one to exit (although there is a facility for applications which need to continue execution in the background). Also, as in old Palm OS and desktop operating systems like Mac OS, we will only support running a single simultaneous instance of any given application.

The Application Manager will handle the high-level operations of launching applications, and provides a number of APIs to applications and to the system for access to these services. It will maintain a list of currently running apps, and will keep track of which one is the "primary" or "main UI" app. This special status is used to coordinate the display and hiding of UI when the user moves between applications. Note that an application that is not the main UI app may still put up UI under exceptional circumstances, it is simply recommended that this be done only occasionally (for example to ask the user for a password), and that it be in the form of a modal dialog. The user's attention is generally focused on the main UI app, and so UI from background apps is often an interruption. It is expected that most applications will not run in background mode.

Detailed documentation on the Attention Manager can be found here.

How Applications Get Installed

Applications are packaged in a format called a bundle. A bundle is a collection of files stored in a cramfs disk image (similar to a .iso or a Mac TM .dmg file), and usually cryptographically signed. A bundle always contains a file called "Manifest.xml". That file contains meta information about the rest of the bundle: what it is, default settings, preferences, etc. All applications are packaged as bundles, but things that are not applications (like data) can also be packaged as bundles. By wrapping an entire application as a bundle, users and programs can deal with arbitrarilycomplicated things as a single file. Bundles have the extension ".bar" (for "bundle archive").

An application is linked as a dynamic library (by using the "shared" option to gcc), with the entry point "alp_main()" instead of the conventional main(). You can see a sample"hello world" application in directory hiker/main/samples. You can see the linker options used in the Makefile in the same directory.

Bundle Manager

The Hiker component that processes bundles is Bundle Manager. Bundle Manager is responsible for controlling how applications, and supplemental data for applications (libraries, resources, etc.), are loaded onto an ALP system, manipulated, transmitted off to other systems, and removed.

In a real system, new applications will appear on the device through the Exchange
Manager, or through the insertion of a memory card. There are no corresponding events in our sample code, so instead in our demo, we inform the Bundle Manager of a new app by a call to alp_bundle_register().

The Bundle Manager is the sole way in which third-party applications are distributed and loaded onto a device. Applications are allowed to read the files in their bundles directly, via the POSIX file i/o routines. Apart from that, the Bundle Manager server is the only software that can access the bundle folders on the internal filesystem. Users have to interact with Bundle Manager to install or remove software, and that software must be in bundle form.

The Bundle Manager is designed around the notion of 'Bundles' as concrete immutable lumps of information which are managed on a device, where each Bundle can contain an arbitrary amount of data in a format appropriate to that Bundle. Each Bundle type is defined both in terms of how it is stored on the device, and as a "flattened" format suitable for transmission as a stream out of the device. (These formats may be the same, different, or overlap at various times).

The Bundle Manager combines a file format for distributing single files that contain applications and all their dependencies (application name, icon, localized resources, dependant libraries, etc) along with functions for installing, removing, and enumerating application “bundles”. The Bundle Manager takes care of allocation of per-application storage locations in writeable storage in the file system, and providing access to localized resources contained within the bundle. Through the Bundle Manager enumeration mechanism, multiple application types are merged and can be launched through a common mechanism. We would include the SDK tool that is necessary to create application bundles from a set of files.

Although binary executables could be loaded onto a device through other means (say, an FTP client dumping a file to the /tmp folder), the launcher and other system components would not provide any UI to launch that executable, nor provide any means to execute it with other than the most restricted permissions.

Bundle Manager also supports:

  • Finding bundles by name
  • Finding bundles by a variety of other characteristics
  • Obtaining information about a bundle
  • Moving bundles between stores
  • Finding what bundle code is running from
  • Opening a bundle for direct access
  • Retrieving files from a bundle
  • Manipulating flattened bundle images, with streaming APIs
  • URL convenience routines which allow a consistent URL format to reference any
    bundle and resource/library on the system. These are names in reverse DNS form,
    like bar:com.access.apps.phone

Application helper routines to retrieve localized icons and names for an app in a
bundle There is a GUI component called the "Launcher" that makes extensive use of Bundle Manager to retrieve information about available applications, and display it in a GUI. The Bundle Manager provides easy access to application resources for developers, as well as maintaining state about Bundles present in the system.

Since it is a GUI component, and Hiker is GUI-neutral, Launcher is not part of this
release. Bundle Manager knows about all bundle types, permitting a single launcher to handle native (ARM), Java, and M68K applications. The Hiker release only includes code for native ARM applications.

Detailed documentation on the Bundle Manager can be found here.

Starting and Stopping Applications

From experience with PalmOS we conclude that handheld devices work best when apps don't try to share the limited screen space. Only one app will use the GUI at a time. Furthermore, you almost never exit an application explicitly. Typically, you start another application (by pressing the home key or the launch button, etc). The Application Server component then ends the current application for you, and starts the new application in its place.

There are no application buttons in our sample code, so instead we explicitly ask the
application server to tell the native process launcher to load the shared object that is the application and then to jump to the app entry point in the shared object, the function alp_main(). The routine that we call to achieve this is listed in the next section.

The Application Server

The application server or "appserver" is a Linux daemon that starts when the system
boots. From the background, it provides these services:

  • provides a way to start applications, and control their lifetime
  • prevents more than one instance of the same app from running
  • may also provide default behavior for system events (such as handling dedicated keys, or clamshell open/close).

You can review the public API for the appserver here. You will see routines like

alp_status_t alp_app_launch

(const char *pkgID, int argc, char *const argv[], pid_t *outPID)

That routine tells the application server to tell the native process launcher to start the the stated application.

Note: Bundles used to be called "packages" and some of the header file names still reflect that.

NLPD

We want applications to start as quickly as possible, and we structured the launch code in an unusual way to achieve this. The largest part of application start up time is consumed in the runtime linker. The runtime linker gets the shared libraries ready to run and initializes all of the global variables. Most application code (on handheld devices) uses a small number of the same shared libraries. We reduce startup
time by having a process which is prelaunched and preinitialized with common libraries already loaded into the address space. This application is called "nlpd" for Native Launch Pad Daemon.

When nlpd receives the "launch" order from the application server, it forks a copy of
itself. That copy then uses dlopen() to load the application shared object and invoke
alp_main(). This is significantly faster than the conventional alternative of vfork()
followed by an exec().

This performance optimization requires an application to be a shared library, so it can be loaded into the address space using dlopen. You can see the code in file
servers/NLPD/Native_Process_Launchpad.c. This is the line that causes the dlopen:

g_closure_invoke(ptr, &return_value, 3, params, NULL);

g_closure is a routine in glib that abstracts dlopen.

nlpd sets the current working directory to the directory where the bundle is stored. The application can thus retrieve files, e.g. icons, stored in its bundle. Nlpd also makes some security- and identity-related settings. Because it is the general template for starting a new application process, nlpd is also called the "cookie cutter".

See here for additional details on the application lifecycle components.

Back to "About Hiker..."

Copyright © 2007, The Hiker Project. All rights reserved.