#FirefoxOS

[video+slides] FirefoxOS – HTML5 for a truly world-wide-web (Sapo Codebits 2014)

Chris Heilmann at SAPO codebits
Today the good people at Sapo released the video of my Codebits 2014 keynote.

In this keynote, I talk about FirefoxOS and what it means in terms of bringing mobile web connectivity to the world. I explain how mobile technology is unfairly distributed and how closed environments prevent budding creators from releasing their first app. The slides are “>available on Slideshare as the video doesn’t show them.

There’s also a screencast on YouTube.

Since this event, Google announced their Android One project, and I am very much looking forward how this world-wide initiative will play out and get more people connected.

Photo by José P. Airosa ‏@joseairosa

View full post on Christian Heilmann

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

It’s a wrap! “App Basics for FirefoxOS” is out and ready to get you started

A week ago we announced a series of video tutorials around creating HTML5 apps for Firefox OS. Now we released all the videos and you can watch the series in one go.

wrap
Photo by Olliver Hallmann

The series is aimed at web developers who want to build their first HTML5 application. Specifically it is meant to be distributed in the emerging markets, where Firefox OS is the first option to get an affordable smartphone and start selling apps to the audiences there.

Over the last week, we released the different videos of the series – one each day:

Yesterday we announced the last video in the series. For all of you who asked for the whole series to watch in one go, you now got the chance to do so.

There are various resources you can use:

What’s next?

There will be more videos on similar topics coming in the future and we are busy getting the videos dubbed in other languages. If you want to help us get the word out, check the embedded versions of the videos on Codefirefox.com, where we use Amara to allow for subtitles.

Speaking of subtitles and transcripts, we are currently considering both, depending on demand. If you think this would be a very useful thing to have, please tell us in the comments.

Thanks

Many thanks to Sergi, Jan, Jakob, Ketil, Nathalie and Anne from Telenor, Brian Bondy from Khan Academy, Paul Jarrat and Chris Heilmann of Mozilla to make all of this possible. Technologies used to make this happen were Screenflow, Amazon S3, Vid.ly by encoding.com and YouTube.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Building a FirefoxOS App for my favorite Internet radio station

I recently created a Firefox OS app for my favourite radio station — radio paradise. It was a lot of fun making this app, so I thought it would be good to share some notes about how I built it.

The audio tag

It started by implementing the main functionality of the app, playing an ogg stream I got from the Internet radio station, using the HTML5 audio element

<audio src="http://stream-sd.radioparadise.com/rp_192m.ogg" controls preload></audio>

That was easy! At this point our app is completely functional. If you don’t believe me, checkout this jsfiddle. But please continue reading, since there will be a few more sweet features added. In fact, checkout the short video below to see how it will turn out.

Because this content belongs to radio paradise, before implementing the app, I contacted them to ask for their permission to make a Firefox OS app for their radio station; they responded:

Thanks. We’d be happy to have you do that. Our existing web player is html5-based. That might be a place to start. Firefox should have native support for our Ogg Vorbis streams.

I couldn’t have asked for a more encouraging response, and that was enough to set things in motion.

Features of the app

I wanted the app to be very minimal and simple — both in terms of user experience and the code backing it. Here is a list of the features I decided to include:

  • A single, easy to access, button to play and pause the music
  • Artist name, song title and album cover for the current song playing should fill up the interface
  • Setting option to select song quality (for situation when bandwidth is not enough to handle highest quality)
  • Setting option to start app with music playing or paused
  • Continue playing even when the app is sent to the background
  • Keep the screen on when the app is running in the forground

Instead of using the HTML tag, I decided to create the audio element and configure it in JavaScript. Then I hooked up an event listener for a button to play or stop music.

  var btn = document.getElementById('play-btn');
  var state = 'stop';
  btn.addEventListener('click', stop_play);
 
  // create an audio element that can be played in the background
  var audio = new Audio();
  audio.preload = 'auto';
  audio.mozAudioChannelType = 'content';
 
  function play() {
    audio.play();
    state = 'playing';
    btn.classList.remove('stop');
    btn.classList.add('playing');
  }
 
  function stop() {
    audio.pause();
    state = 'stop';
    btn.classList.add('stop');
    btn.classList.remove('playing');
  }
 
  // toggle between play and stop state
  function stop_play() {
    (state == 'stop') ? play() : stop();
  }

Accessing current song information

The first challenge I faced was accessing the current song information. Normally we should not need any special privilege to access third party API’s as long as they provide correct header information. However, the link radio paradise provided me for getting the current song information did not allow for cross origin access. Luckily FirefoxOS has a special power reserved for this kind of situation — systemXHR comes to the rescue.

function get_current_songinfo() {
  var cache_killer = Math.floor(Math.random() * 10000);
  var playlist_url =
    'http://www.radioparadise.com/ajax_rp2_playlist.php?' +
    cache_killer;
  var song_info = document.getElementById('song-info-holder');
  var crossxhr = new XMLHttpRequest({mozSystem: true});
  crossxhr.onload = function() {
    var infoArray = crossxhr.responseText.split('|');
    song_info.innerHTML = infoArray[1];
    next_song = setInterval(get_current_songinfo, infoArray[0]);
    update_info();
  };
  crossxhr.onerror = function() {
    console.log('Error getting current song info', crossxhr);
    nex_song = setInterval(get_current_singinfo, 200000);
  };
  crossxhr.open('GET', playlist_url);
  crossxhr.send();
  clearInterval(next_song);
}

This meant that the app would have to be privileged and thus packaged. I normally would try to keep my apps hosted, because that is very natural for a web app and has several benefits including the added bonus of being accessible to search engines. However, in cases such as this we have no other option but to package the app and give it the special privileges it needs.

{
  "version": "1.1",
  "name": "Radio Paradise",
  "launch_path": "/index.html",
  "description": "An unofficial app for radio paradise",
  "type": "privileged",
  "icons": {
    "32": "/img/rp_logo32.png",
    "60": "/img/rp_logo60.png",
    "64": "/img/rp_logo64.png",
    "128": "/img/rp_logo128.png"
  },
  "developer": {
    "name": "Aras Balali Moghaddam",
    "url": "http://arasbm.com"
  },
  "permissions": {
    "systemXHR": {
      "description" : "Access current song info on radioparadise.com"
    },
    "audio-channel-content": {
      "description" : "Play music when app goes into background"
    }
  },
  "installs_allowed_from": ["*"],
  "default_locale": "en"
}

Updating song info and album cover

That XHR call to radio paradise proides me with three important pieces of information:

  • Name of the current song playing and it’s artist
  • An image tag containing the album cover
  • Time left to the end of current song in miliseconds

Time left to the end of current song is very nice to have. It means that I can execute the XHR call and update the song information only once for every song. I first tried using the setTimeout function like this:

//NOT working example. Can you spot the error?
crossxhr.onload = function() {
  var infoArray = crossxhr.responseText.split('|');
  song_info.innerHTML = infoArray[1];
  setTimeout('get_current_songinfo()', infoArray[0]);
  update_info();
};

To my surprise, that did not work, and I got a nice error in logcat about a CSP restriction. It turns out that any attempt at dynamically executing code is banned for security reasons. All we have to do in this scenario to avoid the CSP issue is to pass a callable object, instead of a string.

  // instead of passing a string to setTimout we pass
  // a callable object to it
  setTimeout(get_current_songinfo, infoArray[0]);

radio paradise mobile web app running on FirefoxOS

With a bit of CSS magic, things started to fall into place pretty quickly

Adding a unique touch

One of the great advantages of developing mobile applications for the web is that you are completely free to design your app in any way you want. There is no enforcement of style or restriction on interaction design innovation. Knowing that, it was hard to hold myself back from trying to explore new ideas and have some fun with the app. I decided to hide the settings behind the main content and then add a feature so user can literally cut open the app in the middle to get to setting. That way they are tucked away, but still can be discovered in an intuitive way. For UI elements in the setting page to toggle options I decided to give Brick a try., with a bit of custom styling added.

radio paradise app settings

User can slide open the cover image to access app settings behind it

Using the swipe gesture

As you saw in the video above, to open and close the cover image I use pan and swipe gestures. To implement that, I took gesture detector from Gaia. It was very easy to integrated the gesture code as a module into my app and hook it up to the cover image.

Organizing the code

For an app this small, we do not have to use modular code. However, since I have recently started to learn about AMD practices, I decided to use a module system. I asked James Burke about implications of using requirejs in an app like this. He suggested I use Alameda instead, since it is geared toward modern browsers.

Saving app settings

I wanted to let users choose stream quality as well as whether they want the app to start playing music as soon as it opens. Both of these options need to be persisted somewhere and retrieved when the app starts. I just needed to save a couple of key/value pairs. I went to #openwebapps irc channel and asked for advice. Fabrice pointed me to a nice piece of code in Gaia (again!) that is used for asynchronous storing of key/value pairs and even whole objects. That was perfect for my use case, so I took it as well. Gaia appears to be a goldmine. Here is the module I created for settings.

define(['helper/async_storage'], function(asyncStorage) {
  var setting = {
    values: {
      quality: 'high',
      play_on_start: false
    },
    get_quality: function() {
      return setting.values.quality;
    },
    set_quality: function(q) {
      setting.values.quality = q;
      setting.save();
    },
    get_play_on_start: function() {
      return setting.values.play_on_start;
    },
    set_play_on_start: function(p) {
      setting.values.play_on_start = p;
      setting.save();
    },
    save: function() {
      asyncStorage.setItem('setting', setting.values);
    },
    load: function(callback) {
      asyncStorage.getItem('setting', function(values_obj) {
        if (values_obj) setting.values = values_obj;
        callback();
      });
    }
  };
  return setting;
});

Splitting the cover image

Now we get to the really fun part that is splitting the cover image in half. To achieve this effect, I made two identical overlapping canvas element both of which are sized to fit the device width. One canvas clips the image and keeps the left portion of it while the other keeps the right side.

Each canvas clips and renders half of the image

Each canvas clips and renders half of the image

Here is the code for draw function where most of the action is happening. Note that this function runs only once for each song, or when user changes the orientation of the device from portrait to landscape and vice versa.

function draw(img_src) {
  width = cover.clientWidth;
  height = cover.clientHeight;
  draw_half(left_canvas, 'left');
  draw_half(right_canvas, 'right');
  function draw_half(canvas, side) {
    canvas.setAttribute('width', width);
    canvas.setAttribute('height', height);
    var ctx = canvas.getContext('2d');
    var img = new Image();
    var clip_img = new Image();
    // opacity 0.01 is used to make any glitch in clip invisible
    ctx.fillStyle = 'rgba(255,255,255,0.01)';
 
    ctx.beginPath();
    if (side == 'left') {
      ctx.moveTo(0, 0);
      // add one pixel to ensure there is no gap
      var center = (width / 2) + 1;
    } else {
      ctx.moveTo(width, 0);
      var center = (width / 2) - 1;
    }
 
    ctx.lineTo(width / 2, 0);
 
    // Draw a wavy pattern down the center
    var step = 40;
    var count = parseInt(height / step);
    for (var i = 0; i < count; i++) {
      ctx.lineTo(center, i * step);
 
      // alternate curve control point 20 pixels, every other time
      ctx.quadraticCurveTo((i % 2) ? center - 20 :
        center + 20, i * step + step * 0.5, center, (i + 1) * step);
    }
    ctx.lineTo(center, height);
    if (side == 'left') {
      ctx.lineTo(0, height);
      ctx.lineTo(0, 0);
    } else {
      ctx.lineTo(width, height);
      ctx.lineTo(width, 0);
    }
 
    ctx.closePath();
    ctx.fill();
    ctx.clip();
 
    img.onload = function() {
      var h = width * img.height / img.width;
      ctx.drawImage(img, 0, 0, width, h);
    };
    img.src = img_src;
  }
}

Keeping the screen on

The last feature I needed to add was keeping the screen on when the app is running in foreground and that turned out to be very easy to implement as well. We need to request a screen wake lock

  var lock = window.navigator.requestWakeLock(resourceName);

The screen wake lock is actually pretty smart. It will be automatically released when app is sent to the background, and then will given back to your app when it comes to the foreground. Currently in this app I have not provided an option to release the lock. If in future I get requests to add that option, all I have to do is release the lock that has been obtained before setting the option to false

  lock.unlock();

Getting the app

If you have a FirefoxOS device and like great music, you can now install this app on your device. Search for “radio paradise” in the marketplace, or install it directly from this link. You can also checkout the full source code from github. Feel free to fork and modify the app as you wish, to create your own Internet Radio apps! I would love it if you report issues, ask for features or send pull requests.

Conclusion

I am more and more impressed by how quickly we can create very functional and unique mobile apps using web technologies. If you have not build a mobile web app for Firefox OS yet, you should definitely give it a try. The future of open web apps is very exciting, and Firefox OS provides a great platform to get a taste of that excitement.

Now it is your turn to leave a comment. What is your favourite feature of this app? What things would you have done differently if you developed this app? How could we make this app better (both code and UX)?

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

The Fox is out of the bag #FirefoxOS

FirefoxOS has been my main focus over quite a period of time now. I worked with the system, I helped developers port their apps to it and I spend hours and hours writing about it, making demos and talking to the press and anyone who’d stand still long enough (or sit on a plane next to me). Today I got my reward with the FirefoxOS movement going from “Idea” via “Prototype” to “Developer Preview” and now “Launch”.

As announced today on the Mozilla blog Mozilla and Partners Prepare to Launch First Firefox OS Smartphones and by prepare this means adding the shiny bow to the boxes containing phones that end users will be able to buy.

According to the Telefonica blog announcement this will be very soon indeed and the offer is pretty amazing:

Movistar to offer the ZTE Open for €69, including €30 of balance for prepaid customers and a 4GB microSD card.

Not only is the price very competitive, you get a great phone for that:

I’ve said this many times before, but let me now here repeat the things that really get me excited like a 5 year old on sugar rush about Firefox OS:

  • Firefox OS kills the idea of mobile web connectivity only being for the rich in the western world. Yes, for us in the US or the UK having a new shiny phone every half year is not an issue as companies are killing each other trying to underbid the price and offers of the others. But a usable Android that is not generations behind and hard-wired to a terrible stock browser or an iPhone is just not affordable to everyone. Even worse, if you have no credit card you couldn’t even buy apps for them. This is unfair, elitist and plainly against anything the web stands for. FirefoxOS is affordable, and apps can be bought on prepay or on your phone bill and the OS is the browser which means updates are easy
  • FirefoxOS does not assume a fast, stable and always available connection. When traveling I start hating my Android phone which I love to bits otherwise. Having dozens of megabyte updates over roaming is out of the question and neither is using flaky and slow wireless connections. Firefox OS has no native apps – all of them, including the system apps are written in HTML, CSS and JavaScript. Thus they are much smaller and can have atomic updates instead of having to be replaced as a unit every single time.
  • Firefox OS is the web in your pocket. It is Firefox and nothing else (other than a Linux core to access the hardware). Thus I will not be told to “download the native app” when I go to web sites that are perfectly fine to use.
  • Firefox OS is the platform HTML5 deserves For developers, our HTML5 solutions are finally first-class citizens. We are not shoved into a slower web view and told we can not access the hardware.
  • Firefox OS apps are web distributed apps. Users can go to the marketplace and find our apps by hand or via review or they could search for a certain song, movie, football team and dish and find our app that way. App discovery is as simple as using the web and finding web sites. Instead of having to pay as a developer and be at the mercy of the T&C of closed marketplaces I can publish a Firefox OS app by adding a button and calling the open web apps API. That way my current web site is the ad for my app and all my visitors potential app users.

All of this is obvious to me as a geek but doesn’t mean anything if we don’t get devices in the hands of end users. And this is what happens now – big time! Alcatel, ZTE, Telefonica, Deutsche Telekom, Spain and Poland. The fox really is out of the bag now. And oh how it will roam and run into many other directions. Be part of this, as a web developer, it is the most rewarding platform that will not change from under you at the whim of company goals or shareholder demands.

View full post on Christian Heilmann

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)