Permalink
Browse files

System app template

  • Loading branch information...
1 parent d2424e5 commit a2acd568d393c392ffb215b58e77af500e3d6228 @gbraad committed Jan 5, 2015
View
@@ -0,0 +1,42 @@
+FxOS as a Hardware Platform
+===========================
+
+This is the main application for a display-less hardware platform running on
+Firefox OS.
+
+
+Instructions
+------------
+
+### Deploy on hardware using DevTools
+
+Development deployments can be done using DevTools. Enable certified apps for
+DevTools using the script provided by
+[TWQA/B2G-flash-tool](https://github.com/Mozilla-TWQA/B2G-flash-tool)
+
+```
+$ enable_certified_apps_for_devtools.sh
+```
+
+
+### Deploy on hardware as system application using ADB
+Push from a Gaia development environment
+
+```
+$ APP=system make install-gaia && adb shell stop b2g && adb shell start b2g
+```
+
+
+Authors
+-------
+
+| [!["Gerard Braad"](http://gravatar.com/avatar/e466994eea3c2a1672564e45aca844d0.png?s=60)](http://gbraad.nl "Gerard Braad <me@gbraad.nl>") |
+|---|
+| [@gbraad](https://twitter.com/gbraad) |
+
+
+References
+----------
+
+* Based on [JanOS](https://github.com/janjongboom/janos)
+
View
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style>
+ body {
+ background: black;
+ color: white;
+ }
+
+ .abs-center {
+ margin: auto;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ }
+ </style>
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
+ <meta charset="utf-8">
+
+ <script src="js/bootstrap.js"></script>
+
+ <!-- Stuff from gaia regarding operators and stuff -->
+ <script defer src="js/gaia-helpers/apn_helper.js"></script>
+ <script defer src="js/gaia-helpers/operator_variant_helper.js"></script>
+ <script defer src="js/gaia-helpers/operator_variant.js"></script>
+
+ <!-- Own scripts -->
+ <!--<script defer src="js/[your-script].js"></script>-->
+ </head>
+
+ <body>
+ <img class="abs-center" src="style/icons/icon_189.png" />
+ </body>
+</html>
View
Oops, something went wrong.
View
@@ -0,0 +1,226 @@
+// No clue why this is needed but it works.
+navigator.mozPower.screenBrightness = 0.9;
+
+setTimeout(function() {
+ navigator.mozPower.screenEnabled = true;
+ navigator.mozPower.screenBrightness = 1;
+}, 100);
+
+window.addEventListener('load', function() {
+ navigator.vibrate([ 200, 200, 200 ]);
+
+ // Gecko can send us system messages!
+ var evt = new CustomEvent('mozContentEvent',
+ { bubbles: true, cancelable: false,
+ detail: { type: 'system-message-listener-ready' } });
+ window.dispatchEvent(evt);
+
+ // Load config file
+ var x = new XMLHttpRequest();
+ x.onload = function() {
+ if (x.status !== 200) {
+ return console.error('Could not fetch js/local_settings.json', x.status);
+ }
+
+ var c = x.response;
+ go(c);
+ };
+ x.onerror = function() {
+ return console.error('Could not fetch js/local_settings.json', x.error);
+ go(null);
+ };
+
+ x.open('GET', '/js/local_settings.json');
+ x.responseType = 'json';
+ try {
+ x.send();
+ }
+ catch (ex) {
+ console.error('Could not find js/local_settings.json', ex);
+ go(null);
+ }
+});
+
+function go(config) {
+ window.config = config = config || { roaming: false };
+
+ // Disable data first for some f* reason
+ navigator.mozSettings.createLock().set({
+ 'ril.data.enabled': false,
+ 'ftu.ril.data.enabled': false,
+ 'ril.data.roaming_enabled': false,
+ 'wifi.enabled': false
+ });
+
+ // For every SIM card enable radio
+ (function enableRadio() {
+ [].forEach.call(navigator.mozMobileConnections, function(conn) {
+ conn.addEventListener('radiostatechange', function() {
+ console.log('radiostate is now', conn.radioState);
+ });
+
+ console.log('at startup conn has', conn.radioState);
+
+ function rsc() {
+ // Sometimes radioState is enabled here,
+ // and thats wrong so we should do this again after that
+ if (conn.radioState === 'disabled') {
+ conn.removeEventListener('radiostatechange', rsc);
+ }
+
+ var sre = conn.setRadioEnabled(true);
+ sre.onerror = function() {
+ console.error('Failed to enable radio for', conn);
+ };
+ }
+
+ if (conn.radioState === 'disabled') {
+ rsc();
+ }
+ else {
+ conn.addEventListener('radiostatechange', rsc);
+ }
+ });
+ })();
+
+ window.enableWifi = function() {
+ if (config.network && config.password) {
+ window.reconnectWifi = connectToWifi.bind(this, config.network, config.password);
+ navigator.mozSettings.createLock().set({ 'wifi.enabled': true });
+ }
+ else {
+ console.error('Please specify network / password in local_settings.json');
+ }
+ };
+
+ navigator.mozWifiManager.onenabled = function() {
+ if (!window.reconnectWifi) {
+ return;
+ }
+
+ setTimeout(function() {
+ window.reconnectWifi();
+ }, 1000);
+ };
+ navigator.mozWifiManager.ondisabled = function() {
+ console.log('Wifi was disabled');
+ };
+
+ var lastIp = null;
+ navigator.mozWifiManager.onconnectioninfoupdate = function(e) {
+ if (e.ipAddress && lastIp !== e.ipAddress) {
+ console.log('Wifi now has IP', e.ipAddress);
+ }
+ lastIp = e.ipAddress;
+ };
+
+ var lastWifiStatus = null;
+ navigator.mozWifiManager.onstatuschange = function(e) {
+ if (e.status !== lastWifiStatus) {
+ if (e.status === 'connected') {
+ console.log('Wifi is now connected to', config.network);
+ }
+ else {
+ console.log('Wifi statuschange', e.status);
+ }
+ lastWifiStatus = e.status;
+ }
+ };
+
+ // Connect to Wifi
+ function connectToWifi(network, pass) {
+ console.log('Attempting to connect to', network);
+
+ var n = navigator.mozWifiManager.getNetworks();
+ n.onsuccess = function() {
+ var wifi = n.result.filter(function(w) { return w.ssid === network })[0];
+ if (!wifi) {
+ return console.error('Could not find wifi network "' + network + '"');
+ }
+
+ // Only PSK at the moment
+ wifi.keyManagement = 'WPA-PSK';
+ wifi.psk = pass;
+
+ var req = navigator.mozWifiManager.associate(wifi);
+ req.onsuccess = function() {
+ console.log('Associated with', config.network);
+ };
+ req.onerror = function() {
+ console.error('Associating failed', req.error);
+ };
+ };
+ n.onerror = function(e) {
+ console.error('GetNetworks failed', e);
+ };
+ }
+
+ navigator.mozIccManager.oniccdetected = function(e) {
+ console.log('new icc detected', e.iccId);
+ enableOperatorVariantHandler(e.iccId, 0); // <- multi sim bug would this be
+ };
+
+ function enableOperatorVariantHandler(id, ix) {
+ window.iccManager = navigator.mozIccManager;
+
+ window['ovh' + ix] = new OperatorVariantHandler(id, ix);
+ window['ovh' + ix].init();
+
+ setTimeout(function() {
+ console.log('Tried enabling data');
+ navigator.mozSettings.createLock().set({
+ 'ril.data.enabled': true,
+ 'ftu.ril.data.enabled': true,
+ 'ril.data.roaming_enabled': config.roaming
+ });
+ }, 3000);
+
+ var conn = navigator.mozMobileConnections[ix];
+ var lastState = conn.data.connected;
+ conn.addEventListener('datachange', function(e) {
+ // console.log('datachange', e);
+ if (conn.data.connected === lastState) {
+ return;
+ }
+
+ if (conn.data.connected) {
+ console.log('Has connection over cellular network');
+ }
+ else {
+ console.log('Lost connection over cellular network');
+ }
+
+ lastState = conn.data.connected;
+ });
+ }
+
+ // Autogrant permissions
+ window.addEventListener('mozChromeEvent', function(evt) {
+ var detail = evt.detail;
+ switch (detail.type) {
+ case 'permission-prompt':
+ console.log('autogrant permissions for', detail.permissions);
+
+ var ev2 = document.createEvent('CustomEvent');
+ ev2.initCustomEvent('mozContentEvent', true, true, {
+ id: detail.id,
+ type: 'permission-allow',
+ remember: true
+ });
+ window.dispatchEvent(ev2);
+ break;
+ }
+ });
+}
+
+window.testXhr = function() {
+ var x = new XMLHttpRequest({ mozSystem: true });
+ x.onload = function() {
+ console.log('xhr onload', x.status);
+ };
+ x.onerror = function() {
+ console.error('xhr onerror', x.error);
+ };
+ x.open('GET', 'http://cloudflare.com');
+ x.send();
+};
@@ -0,0 +1,84 @@
+/**
+ * @fileoverview This file provides common helper functions used to manipulate
+ * access point names (APNs)
+ */
+
+/* exported ApnHelper */
+
+(function(exports) {
+ 'use strict';
+
+ /**
+ * List of data network types, see source/dom/system/gonk/ril_consts.js in
+ * mozilla-central. Those match the equivalent Android integer types.
+ */
+ var NETWORK_TYPES = [
+ null,
+ 'gprs',
+ 'edge',
+ 'umts',
+ 'is95a',
+ 'is95b',
+ '1xrtt',
+ 'evdo0',
+ 'evdoa',
+ 'hsdpa',
+ 'hsupa',
+ 'hspa',
+ 'evdob',
+ 'ehrpd',
+ 'lte',
+ 'hspa+',
+ 'gsm'
+ ];
+
+ /**
+ * Filter a list of APNs by network type. This involves comparing the bearer
+ * field if present to the data network type and checking if they match. If
+ * the bearer value of an APN is not defined or is set to 0 then we consider
+ * the APN compatible with any network.
+ *
+ * @param {Array} apns An array of APNs
+ * @param {String} type The network type which the APNs must be compatible
+ * with
+ */
+ function ah_filterByBearer(apns, type) {
+ var typeIdx = NETWORK_TYPES.indexOf(type);
+
+ for (var i = 0; i < apns.length; i++) {
+ var bearer = apns[i].bearer ? +apns[i].bearer : 0;
+
+ if (bearer && (bearer !== typeIdx)) {
+ // This APN is incompatible, remove it from the array
+ apns.splice(i, 1);
+ }
+ }
+ }
+
+ /**
+ * Get an APN from the specified list which is compatible with the specified
+ * MCC, MNC and connection type
+ *
+ * @param {Object} list The global APN list, the format should be the same as
+ * the one used in apn.json
+ * @param {Integer} mcc The mobile country code
+ * @param {Integer} mnc The mobile network code
+ * @param {String} type The network type which the filtered APNs must be
+ * compatible with
+ *
+ * @return {Array} A list of compatible APNs
+ */
+ function ah_getCompatible(list, mcc, mnc, type) {
+ var apns = list[mcc] ? (list[mcc][mnc] || []) : [];
+
+ ah_filterByBearer(apns, type);
+
+ return apns;
+ }
+
+ var ApnHelper = {
+ getCompatible: ah_getCompatible
+ };
+
+ exports.ApnHelper = ApnHelper;
+})(this);
Oops, something went wrong.

0 comments on commit a2acd56

Please sign in to comment.