Writing apps for Firefox OS phones
The Package
Another thing you want to do (otherwise, you won't be able to run your app on the simulator or handset) is write the manifest. The manifest is a JSON summary that contains all the details needed for Firefox OS to run the app correctly.
The manifest.webapp
file must be in the root of the app. The example in Listing 1 gives you an idea of what the file should contain.
Listing 1
Manifest.webapp for Life
Most of the fields in the listing are pretty self-explanatory; however, note in the icons
section that you will have a 60x60-pixel icon and another 128x128 pixels. The handset uses the 60-pixel icon in its list of apps (Figure 2); the 128-pixel icon comes into play if you want to distribute your app through the Firefox OS marketplace, which I talk about a bit later. A handy online guide shows you how to create a thematically consistent icon [4].
The orientation
field in line 16 allows you to decide how your app will be shown on the device: portrait
, landscape
, portrait-primary
, landscape-primary
, portrait-secondary
, or landscape-secondary
.
For example, if you specify portrait-primary
in your manifest file, your app appears in portrait mode with the top of your UI at the top of the device, and the bottom of the UI at the bottom of the device's display. The portrait-secondary
option flips the orientation 180 degrees. By using portrait
, your app will flip in portrait mode depending on how the device is being held, but it will not rotate 90 degrees when you turn the device on its side.
You can also combine these options. For example,
"orientation": ["portrait", "landscape-secondary"]
allows your app to flip either way in portrait mode (right-side up or upside down) and will display correctly on one of its sides but not the other. The Mozilla Developer Network has a good tutorial on how to write a good manifest [5].
The Software
In my example project, I'll be implementing Conway's Game of Life (GoL) [6], which is probably one of the most popular and simplest life simulators. If you are unfamiliar with GoL, check out the "The Game of Life" box.
The Game of Life
In GoL, you set up a culture of cells in a virtual petri dish and then watch the cells reproduce. The rules are simple: Your Petri dish is a grid of square cells. The cells can be alive (filled in) or dead (empty). When you run the simulation, the program calculates the next generation by deciding which cells stay in the same state, which die, and which reproduce according to the following rules:
- If a cell has zero or one neighbor, it dies from isolation; with four or more neighbors, it dies from overcrowding.
- If a cell has two neighbors, it stays in the same state in the next generation (i.e., if it's dead in the current generation, it will be dead in the next generation; if it's alive in the current generation, it will be alive in the following generation).
- If a cell has three neighbors, it either stays the same (if occupied) or comes to life (if empty).
When all the cells are plotted in the newest generation, it becomes the current generation, and the cycle begins again.
These simple rules can lead to extremely complex configurations that are nearly impossible to foresee, unless you have a large tablet of graph paper and, ironically, no life of your own. Consider the R-pentomino initial state as an example (Figure 3). It is a seed of only five cells that grows to an enormous size; generates shapes called gliders, toads, and loaves; and does not stabilize until generation 1,103.
If you have had any experience with JavaScript in the last few years, you will have witnessed the rise of JavaScript libraries, none of which is more popular than jQuery. jQuery [7] has simplified the creation of dynamic web programming to the point of forcing Flash nearly to extinction (which, by the way, is an excellent thing). jCanvas [8], on the other hand, is an extension of jQuery that makes programming on a canvas object much easier.
In my implementation of the GoL (Listing 2), I will use the HTML5 canvas
object as a playing board (line 17). To help, I also will use jQuery and jCanvas (lines 7 and 8). In lines 150 to 159 you can see how easy it is draw a cell on the canvas. Note that because I considered a single pixel too small, I decided to go with a 2x2 box for the cells. Therefore, with a 300x300 canvas, the playing field can hold 150x150 cells.
Listing 2
Life for Firefox OS (index.html)
The code in Listing 2 also uses jQuery extensively to refer to and manipulate some of the elements, such as the status bar (Figure 4), which will slowly appear and then fade out if you tap the playing field twice (the equivalent of a double-click) and show you how many live cells are in the current generation (lines 38-42). The HTML to include the status bar in your app is very simple (lines 22-24), although you will have to modify the status.css
file to use the clean, elegant font provided by Mozilla (Listing 3).
Listing 3
Modified status.css File
The Start(Stop) and Clear buttons (Figure 5) are included in the user interface in lines 18 and 19 (Listing 2). When you click Start or Stop (lines 193-212), you either start the mainLoop
function (which runs the simulation) or stop it.
The Clear button uses a jCanvas function to erase all pixels from the canvas and empties the CULTURE
array that holds the coordinates of the live cells in the current generation (lines 214-220).
The biggest chunk of code (lines 81-142) is the mainloop
mentioned previously. This section calculates the next generation based on the current generation stored in CULTURE
. The most obvious way to do this is to loop over every cell in a 150x150 array and examine each of the eight possible neighbors, changing their states as necessary. However, this approach is a very slow, very inefficient way of doing things.
Instead, the CULTURE
array contains the coordinates of only the live cells in the current generation. By examining only live cells and their immediate neighbors, you can skip enormous empty chunks of the playing board. All of the white space above, between, and below the live cells is ignored (lines 90-138).
The jQuery $.each()
loops over all the elements in CULTURE
and avoids examining a cell twice by storing it in the cellExamined
array (line 106) and skipping it if it is encountered again (line 104). The new cell configuration is gradually stored in the nextCulture
array.
Note that the cells are stored as strings. Thus, cell (130, 45) is stored as [130,45]
. Arrays in JavaScript are flat, so a two-dimensional array like
a = [[130, 45], [20, 130], [45, 10]]
is actually stored like
a = [130, 45, 20, 130, 45, 10]
making searches for duplicate coordinates (i.e., lines 62-71) very difficult. The conversion from string to numbers and back again, which is going on within the loops, certainly has an effect on performance, but the only other way would be to store cells as an array of objects. Unfortunately, looping and searching for duplicates within an array of objects is also difficult, hence the string-based solution.
Finally, nextCulture
is dumped into CULTURE
, and the new generation is drawn to the playing board (lines 140-141).
The Distribution
Now that your app works, it's time to package it and get it distributed. The packaging process is very straightforward. All you need to do is create a ZIP file that has the manifest.webapp
file in its root. In Linux, you would cd
into the root of your app and type:
zip -r <appname>.zip *
Now, you have two choices: You can host the app yourself on your own site, which Mozilla is perfectly okay with, or you can upload it to the Firefox OS Marketplace (Figure 6) [9]. To use the Marketplace, you need a Firefox OS developer account (Figure 7) [10]; the submission process, is very straightforward (Figures 8 and 9).
Apart from providing more exposure with the marketplace, the wizard helps you weed out any errors you might have in your manifest; moreover, in the future, you will be able to sell your apps using Mozilla's framework.
« Previous 1 2 3 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Wine 10 Includes Plenty to Excite Users
With its latest release, Wine has the usual crop of bug fixes and improvements, along with some exciting new features.
-
Linux Kernel 6.13 Offers Improvements for AMD/Apple Users
The latest Linux kernel is now available, and it includes plenty of improvements, especially for those who use AMD or Apple-based systems.
-
Gnome 48 Debuts New Audio Player
To date, the audio player found within the Gnome desktop has been meh at best, but with the upcoming release that all changes.
-
Plasma 6.3 Ready for Public Beta Testing
Plasma 6.3 will ship with KDE Gear 24.12.1 and KDE Frameworks 6.10, along with some new and exciting features.
-
Budgie 10.10 Scheduled for Q1 2025 with a Surprising Desktop Update
If Budgie is your desktop environment of choice, 2025 is going to be a great year for you.
-
Firefox 134 Offers Improvements for Linux Version
Fans of Linux and Firefox rejoice, as there's a new version available that includes some handy updates.
-
Serpent OS Arrives with a New Alpha Release
After months of silence, Ikey Doherty has released a new alpha for his Serpent OS.
-
HashiCorp Cofounder Unveils Ghostty, a Linux Terminal App
Ghostty is a new Linux terminal app that's fast, feature-rich, and offers a platform-native GUI while remaining cross-platform.
-
Fedora Asahi Remix 41 Available for Apple Silicon
If you have an Apple Silicon Mac and you're hoping to install Fedora, you're in luck because the latest release supports the M1 and M2 chips.
-
Systemd Fixes Bug While Facing New Challenger in GNU Shepherd
The systemd developers have fixed a really nasty bug amid the release of the new GNU Shepherd init system.