Getting started with Firefox OS and Open Web Apps
14:30 Introduction
15:30 Get set up
15:45 Start first app
16:30 Break
16:45 Hacking
Agenda:
Using HTML5, CSS and JavaScript together with a number of APIs to build apps and customize the UI.
Firefox OS
Foxconn
Open Web Apps
HTML5 + manifest file (JSON)
Steps to Take
Develop Web App using HTML5, CSS, & Javascript1.
Create an app manifest file2.
Publish/install the app3.
1. Develop Web App using HTML5, CSS & JavaScript
Reuse any existing web site/app or develop from scratch with open web standards.
Utilize HTML5 features such as localStorage, offline manifest, IndexedDB and access Web APIs for more options.
Responsive web design for adapting to varying resolutions and screen orientation.
2. Create an app manifest file
Create a file with a .webapp extension
{ "version": "1", "name": "Firefox OS Boilerplate App", "launch_path": "/index.html", "description": "Boilerplate Firefox OS app", "icons": { "16": "/images/logo16.png", "32": "/images/logo32.png", "48": "/images/logo48.png", "64": "/images/logo64.png", "128": "/images/logo128.png" }, "developer": { "name": "Robert Nyman", "url": "http://robertnyman.com" }, "installs_allowed_from": ["*"], "default_locale": "en"}
Serve with Content-type/MIME type:
application/x-web-app-manifest+json
Apache - in mime.types:
application/x-web-app-manifest+json webapp
Apache - in .htaccess:
AddType application/x-web-app-manifest+json webapp
NGinx - in mime.types:
types { text/html html htm shtml; text/css css; text/xml xml; application/x-web-app-manifest+json webapp;}
IIS:
In IIS Manager, right-click the local computer, and click Properties.
Click the MIME Types button.
Click New.
In the Extension box, type the file name extension.
In the MIME type box, type a description that exactly matches the file type defined on the computer.
Click OK.
curl -I http://mozillalabs.com/manifest.webapp
3. Publish/install the app
Firefox Marketplace
https://marketplace.firefox.com/
https://marketplace.firefox.com/developers/
Installing/hosting the app
var request = navigator.mozApps.install( "http://robnyman.github.com/Firefox-OS-Boilerplate-App/manifest.webapp", { user_id: "some_user" });
request.onsuccess = function() { // Success! Notification, launch page etc}
request.onerror = function() { // Failed. this.error.name has details}
Build excellent interfaces!
Packaged & hosted apps
WebAPIs
Security Levels
Web Content
Regular web content
Installed Web App
A regular web app
Privileged Web App
More access, more responsibility
Certified Web App
Device-critical applications
https://wiki.mozilla.org/WebAPI#Planned_for_initial_release_of_B2G_.28aka_Basecamp.29
"permissions": { "contacts": { "description": "Required for autocompletion in the share screen", "access": "readcreate" }, "alarms": { "description": "Required to schedule notifications" }}
PERMISSIONS
Vibration API (W3C)
Screen Orientation
Geolocation API
Mouse Lock API (W3C)
Open WebApps
Network Information API (W3C)
Battery Status API (W3C)
Alarm API
Web Activities
Push Notifications API
WebFM API
WebPayment
IndexedDB (W3C)
Ambient light sensor
Proximity sensor
Notification
REGULAR APIS
BATTERY STATUS API
var battery = navigator.battery;if (battery) { var batteryLevel = Math.round(battery.level * 100) + "%", charging = (battery.charging)? "" : "not ", chargingTime = parseInt(battery.chargingTime / 60, 10), dischargingTime = parseInt(battery.dischargingTime / 60, 10); // Set events battery.addEventListener("levelchange", setStatus, false); battery.addEventListener("chargingchange", setStatus, false); battery.addEventListener("chargingtimechange", setStatus, false); battery.addEventListener("dischargingtimechange", setStatus, false); }
NOTIFICATION
var notification = navigator.mozNotification;notification.createNotification( "See this", "This is a notification", iconURL);
SCREENORIENTATION API
// Portrait mode:screen.mozLockOrientation("portrait");
/* Possible values: "landscape" "portrait" "landscape-primary" "landscape-secondary" "portrait-primary" "portrait-secondary"*/
VIBRATION API
// Vibrate for one secondnavigator.vibrate(1000);
// Vibration pattern [vibrationTime, pause,…]navigator.vibrate([200, 100, 200, 100]);
// Vibrate for 5 secondsnavigator.vibrate(5000);
// Turn off vibrationnavigator.vibrate(0);
WEB PAYMENTS
var pay = navigator.mozPay(paymentToken);pay.onsuccess = function (event) { // Weee! Money!};
mozmarket.receipts.Prompter({ storeURL: "https://marketplace.mozilla.org/app/myapp", supportHTML: '<a href="mailto:[email protected]">email [email protected]</a>', verify: true});
NETWORK INFORMATION API
var connection = window.navigator.mozConnection, online = connection.bandwidth > 0, metered = connection.metered;
ALARM API
var alarmId1, request = navigator.mozAlarms.add( new Date("May 15, 2012 16:20:00"), "honorTimezone", { mydata: "my event" } ); request.onsuccess = function (event) { alarmId1 = event.target.result;};
request.onerror = function (event) { console.log(event.target.error.name);};
var request = navigator.mozAlarms.getAll();
request.onsuccess = function (event) { console.log(JSON.stringify(event.target.result));};
request.onerror = function (event) { console.log(event.target.error.name);};
navigator.mozSetMessageHandler( "alarm", function (message) { // Note: message has to be set in the manifest file console.log("Alarm fired: " + JSON.stringify(message)); });
DEVICEPROXIMITY
window.addEventListener("deviceproximity", function (event) { // Current device proximity, in centimeters console.log(event.value); // The maximum sensing distance the sensor is // able to report, in centimeters console.log(event.max); // The minimum sensing distance the sensor is // able to report, in centimeters console.log(event.min);});
AMBIENT LIGHT EVENTS
window.addEventListener("devicelight", function (event) { // The lux values for "dim" typically begin below 50, // and the values for "bright" begin above 10000 console.log(event.value);});
PAGE VISIBILITY
document.addEventListener("visibilitychange", function () { if (document.hidden) { console.log("App is hidden"); } else { console.log("App has focus"); }});
Device Storage API
Browser API
TCP Socket API
Contacts API
systemXHR
PRIVILEGED APIS
DEVICE STORAGE API
var deviceStorage = navigator.getDeviceStorage("videos");
var storage = navigator.getDeviceStorage("videos"), cursor = storage.enumerate(); cursor.onerror = function() { console.error("Error in DeviceStorage.enumerate()", cursor.error.name);};
cursor.onsuccess = function() { if (!cursor.result) return; var file = cursor.result;
// If this isn't a video, skip it if (file.type.substring(0, 6) !== "video/") { cursor.continue(); return; }
// If it isn't playable, skip it var testplayer = document.createElement("video"); if (!testplayer.canPlayType(file.type)) { cursor.continue(); return; }};
CONTACTS API
var contact = new mozContact();contact.init({name: "Tom"});
var request = navigator.mozContacts.save(contact);request.onsuccess = function() { console.log("Success");};
request.onerror = function() { console.log("Error")};
WebTelephony
WebSMS
Idle API
Settings API
Power Management API
Mobile Connection API
WiFi Information API
WebBluetooth
Permissions API
Network Stats API
Camera API
Time/Clock API
Attention screen
Voicemail
CERTIFIED APIS
WEBTELEPHONY
// Telephony objectvar tel = navigator.mozTelephony;
// Check if the phone is muted (read/write property)console.log(tel.muted);
// Check if the speaker is enabled (read/write property)console.log(tel.speakerEnabled);
// Place a callvar cal = tel.dial(“123456789”);
// Receiving a calltel.onincoming = function (event) { var incomingCall = event.call;
// Get the number of the incoming call console.log(incomingCall.number);
// Answer the call incomingCall.answer();};
// Disconnect a callcall.hangUp();
// Iterating over calls, and taking action depending on their changed statustel.oncallschanged = function (event) { tel.calls.forEach(function (call) { // Log the state of each call console.log(call.state); });};
WEBSMS
// SMS objectvar sms = navigator.mozSMS;
// Send a messagesms.send("123456789", "Hello world!");
// Recieve a messagesms.onreceived = function (event) { // Read message console.log(event.message);};
WEB ACTIVITIES
Interacting with the camera
var activity = new MozActivity({ name: "view", data: { type: "image/png", url: ... }});
activity.onsuccess = function () { console.log("Showing the image!");};
activity.onerror = function () { console.log("Can't view the image!");};
{ "activities": { "share": { "filters": { "type": ["image/png", "image/gif"] } "href": "sharing.html", "disposition": "window" } }}
var register = navigator.mozRegisterActivityHandler({ name: "view", disposition: "inline", filters: { type: "image/png" }});
register.onerror = function () { console.log("Failed to register activity");}
navigator.mozSetMessageHandler("activity", function (a) { var img = getImageObject(); img.src = a.source.url; // Call a.postResult() or a.postError() if // the activity should return a value});
Future APIs
Resource lock API
UDP Datagram Socket API
Peer to Peer API
WebNFC
WebUSB
HTTP-cache API
Calendar API
Spellcheck API
LogAPI
Keyboard/IME API
WebRTC
FileHandle API
Sync API
Web Apps from Mozilla
Dialer
Contacts
Settings
SMS
Web browser
Gallery
Video Player
Music Player
E-mail (POP, IMAP)
Calendar
Alarm Clock
Camera
Notes
First Run Experience
Notifications
Home Screen
Mozilla Marketplace
System Updater
Localization Support
Web Components & Mozilla Brick
<x-flipbox> <div>I'm the front face.</div> <div>And I'm the back face.</div></x-flipbox>
// assume that toggleButton and flipBox are already// defined as their respective DOM elementstoggleButton.addEventListener("click", function(){ flipBox.toggle(); });
appbarcalendardatepickerdeckflipboxiconbuttonlayout
slideboxslidertabbartoggletogglegrouptooltip
Get started
https://addons.mozilla.org/firefox/addon/firefox-os-simulator/
FIREFOX OS BOILERPLATE APP
https://github.com/robnyman/Firefox-OS-Boilerplate-App
Trying things out