The answer is always in front of your eyes.
« Friday, January 31, 2014 »


Whoever is reading this, I've got some problems recently but now I feel much better and I felt that this discovery I made today was worth spreading. I've been messing with FirefoxOs for a couple of days and I find it magic. It's pretty far from perfect, it's probably barely useable for someone with an Android/iOS/wp8 background etc. From my point of view, FirefoxOS is a pretty impressive piece of software.

I remember when I was in college and one of my teacher was telling us how html is going to replace everything in some ways. At that time, I was pretty convinced that HTML with Css1 was pretty far from anything useable and that with the IE6 crap better use GTK trough a thin client with a xserver than writing HTML applications. And even now, I'm pretty sure that we could run TheGimp using a remote XSession and it would probably run flawlessly as our internet connections are now much more faster than it was 7 years ago.

I'll have to admit that now with HTML5 it might even feel much more comfortable to write html 5 apps than to write a gui application with GTK or other frameworks.

So I gave it a try and I'm quite amazed because it works… and all you need is Firefox and a text editor.

This article got me started nicely:

http://12devsofxmas.co.uk/2012/12/day-2-lets-make-a-firefoxos-app/

It's pretty easy to understand but when I finished it I wanted to do something funkier. I wanted to show a list of the current contacts I have in the phone and when clicked, it would open their contact details. It seems quite easy but the documentation for firefoxos is pretty new and might be even lacking in some ways.

Looking here, you'll be able to get some easy to understand use case on how to use contacts in firefoxos.

https://developer.mozilla.org/en-US/docs/WebAPI/Contacts

In my case, I used the getAll function to get all contacts.

var allContacts = navigator.mozContacts.getAll();

allContacts.onsuccess = function(event) {
  var cursor = event.target;
  if (cursor.result) {
    // when there is a contact
  } else {
    // when cursor is empty
  }
}

allContacts.onerror = function() {
  console.warn("Something went terribly wrong! :(");
}

Pretty easy, now the hardest part. To open a new application, you have to create a new Activity using the WebActivity API. For that you'll have to read this. It's still quite easy to understand. So the code to start an activity is as small as this:

var activity = new MozActivity({
  // Ask for the "pick" activity
  name: "pick",

  // Provide the data required by the filters of the activity
  data: {
    type: "image/jpeg"
  }
});

The name is the name of the activity that you want to open, it is located inside the manifest.webapp. As I wanted to open the contact details, I had to find the activities defined into the webapp for the applications. As it turns out, while searching I found out that the contacts are inside the communications application (sounds weird but that's where it is).

Here's the relevant part of the manifest:

  "activities": {
    ...
    "open": {
      "filters": {
        "type": "webcontacts/contact"
      },
      "disposition": "inline",
      "href": "/contacts/index.html?open",
      "returnValue": true
    },
    "new": {
      "filters": {
        "type": "webcontacts/contact"
      },
      "disposition": "inline",
      "href": "/contacts/index.html?new",
      "returnValue": true
    },
    "update": {
      "filters": {
        "type": "webcontacts/contact"
      },
      "disposition": "inline",
      "href": "/contacts/index.html?update",
      "returnValue": true
    }
    ...
  },

Looking at the filters part, I guessed that webcontacts/contact is what I'm looking for and the open activity is really what I was looking for. So I defined my MozActivity to this:

link.addEventListener("click", function (event) {
  event.preventDefault();
      var activity = new MozActivity({
          name: "open",
          data: {
              type: "webcontacts/contact",
              id: contact.id
          }
      });
  });

It didn't work at first and I found this part of the code here. I felt it magically looked like what I was looking for and expected the id to be found but I was wrong. This line var hasParams = window.location.hash.split('?'); mislead me thinking that the id should be present inside the url. I read somewhere that we could pass parameters inside the url while opening an activity with the href property but it didn't work. It did open the contact page but it never loaded the contact details. The debugger didn't even let me debug the communication code so I was left to myself…
Apparently the problem was in front of my eyes all the time and I was so bugged by the line above that I didn't think about it yet. Even if the debugger didn't work, human have a brain and I started to do the steps in my mind.

When an activity is called in FirefoxOS, it will call a handle function into the ActivityHandler. In my case it was the open activity into the switch case at line 58 of activities.js. Then we jump to the line 31 of the same file. At line 42, the magic happens and it was there all the time and I couldn't see it. activity.source is apparently the object we used to create the activity. In our case, source.name should be “open” and source.data.type should be “webcontacts/contact”. But at line 42 it reads this: var originalParams = activity.source.data.params;, and then it construct a new url with the params defined there. And if you guessed right, all I had to do is to write this instead of what I wrote earlier to get it work.

    var activity = new MozActivity({
              name: "open",
              data: {
                  type: "webcontacts/contact",
                  params: {
                      id: contact.id
                  }
              }
          });

It's pretty clean and it works, if you read carefully the documentation available on MDN, everything should be clear except that if you want to call certain activities by yourself, it's probably not documented and you'll have to dig the code. Fortunately, the code base of Gaia seems pretty clean and it's not terrible to find anything you need to know. Unlike Android's Intent, the firefox os activities aren't really well documented yet and if you want to do something. It feels like your probably the first to do it yet.

I believe that with time things will get better and that firefox os really rocks even though it's not for everyone yet. But it's a question of time. The integration of firefoxos with firefox is quite awesome. You won't see any kind of integration with other mobile platforms in the near future.

comments powered by Disqus

Copyright © 2015 Loïc Faure-Lacroix