Conceitos
Antes de colocarmos as mãos na massa e construírmos nosso primeiro app, vamos aprender alguns conceitos básicos para desenvolvimento para Firefox OS. Como aprendemos na introdução, os apps são baseados em HTML5 assim como uma página web, mas ainda não sabemos o que os diferenciam.
Se pensarmos nas demais plataformas móveis que conhecemos, podemos chegar a alguns requisitos mínimos para um aplicativo móvel:
- Possuir um ícone.
- Possuir um nome.
- Funcionar offline quando possível.
No Firefox OS, um aplicativo é, a grosso modo, uma página web que possui um ícone, um nome e pode funcionar offline – dependendo de como o desenvolvedor fizer o seu trabalho. Todas essas informações a respeito de um aplicativo, tais como nome e ícone, são definidas em um arquivo de manifesto, como veremos na próxima sessão.
O Manifesto de Aplicativo
O manifesto é um arquivo do tipo JSON que descreve um aplicativo. Em geral esse arquivo se chama manifest.webapp e fica ao lado do seu arquivo principal HTML que normalmente chama index.html.
Exemplo de Manifesto
1 {
2 "name": "Memos",
3 "version": "1.1",
4 "description": "A simple memo taking app",
5 "launch_path": "/index.html",
6 "permissions": {
7 "storage": {
8 "description": "Required for storing and retrieving notes."
9 }
10 },
11 "developer": {
12 "name": "Andre Garzia",
13 "url": "http://andregarzia.com"
14 },
15 "icons": {
16 "60": "/style/icons/icon_60.png",
17 "128": "/style/icons/icon_128.png"
18 }
19 }
Acima podemos ver um exemplo de manifesto do aplicativo chamado memos4. Entre outras coisas, ele descreve quem fez o aplicativo, qual ícone e nome do mesmo, qual arquivo é utilizado para carregar o app (nesse caso o index.html) e quais permissões de acesso ao hardware ele precisa. Esse arquivo é utilizado pelo Firefox OS para adicionar o aplicativo ao aparelho e pelo Firefox Marketplace para criar a listagem do mesmo na loja como podemos ver na imagem abaixo:

Listagem do memos no Firefox Marketplace
A mesma informação do manifesto é utilizada para colocar o aplicativo no aparelho, como podemos ver na captura de tela do simulador a seguir:

Memos no simulador
De posse dos seus arquivos HTML, CSS, JavaScript e de um arquivo de manifesto, você ja tem um app pronto para rodar no Firefox OS. Continuando o tópico sobre aplicativos, vamos aprender os tipos de aplicativos existentes.
Tipos de aplicativo
No Firefox OS existem dois tipos de aplicativos: aplicativos hospedados e aplicativos empacotados.
- Aplicativos Hospedados: ficam armazenados em um servidor web, assim como um site. Quando utilizados pelo usuário, é feito um acesso ao servidor remoto caso seus arquivos não estejam no cache.
- Aplicativos Empacotados: são distribuídos como um arquivo zip e são copiados para o aparelho durante a instalação.
Existem prós e contras para as duas soluções. Aplicativos hospedados são mais fáceis de atualizar, basta trocar os arquivos no servidor. Porém, são mais difíceis de fazer funcionar offline, pois precisam da utilização do appcache para isso. Além disso aplicativos hospedados só podem acessar um conjunto restrito de WebAPIs portanto não podem fazer tudo que um aplicativo empacotado pode.
Aplicativos empacotados, por outro lado, estão no telefone desde a instalação e não precisam verificar cache e nem nada antes de executar. No entanto, a atualização é mais complexa e inclui o envio da nova versão do app para o Firefox Marketplace e/ou a criação de rotinas de atualização dentro do mesmo, caso você o distribua fora do marketplace. Esses aplicativos podem acessar APIs que não estão disponíveis para os aplicativos hospedados portanto ao serem enviados para o Firefox Marketplace eles devem passar por um processo de revisão e aprovação do código para garantir a segurança do usuário.
Não existe uma regra sobre qual tipo de aplicativo usar. Pessoalmente, prefiro construir aplicativos empacotados para não ter que lidar com o appcache e não ter que ficar hospedando o app em algum servidor. Aplicativos empacotados distribuídos no Firefox Marketplace ficam hospedados nos servidores da Mozilla e, para mim, isso é mais fácil.
Vale a pena dizer que o mundo das ferramentas para desenvolvimento com JavaScript5 já produziu geradores de arquivos de appcache que facilitam muito a vida de quem está criando apps hospedados.
A escolha é de cada um, porém, ao longo deste livro utilizarei aplicativos empacotados, pois é mais fácil e mantém nosso foco nos apps e não na forma de hospedá-los e servi-los via web. Para quem quiser saber mais sobre aplicativos hospedados, basta checar o link de aplicativos hospedados na central do desenvolvedor.
Agora que já falamos sobre os dois tipos de aplicativo que o Firefox OS suporta, vamos focar nos diferentes níveis de acesso ao sistema que um app pode ter.
Níveis de acesso ao hardware
Existem três níveis de acesso ao hardware no Firefox OS. Cada nível possui APIs que pode ou não acessar.
- Normal: Os aplicativos normais possuem acesso às WebAPIs mais frequentemente utilizadas, tais como geolocalização e obter foto da câmera. Aplicativos hospedados e aplicativos empacotados que não declarem um tipo no manifesto são, por definição, normais.
- Privilegiado: Um aplicativo privilegiado tem acesso a todas as APIs disponíveis para um app normal e mais algumas. Uma exigência é que todos os aplicativos privilegiados sejam empacotados, ou seja, você não pode ter um aplicativo hospedado que seja privilegiado. Esses aplicativos têm acesso a APIs mais “profundas” do Firefox OS, como a API de contatos sem interação com usuário.
- Certificado: Aplicativos certificados têm acesso total ao hardware e só podem ser construídos pela Mozilla e seus parceiros de hardware. Eles têm acesso, por exemplo, ao sistema de telefonia. Um exemplo de aplicativo certificado é o discador do Firefox OS.
Em geral a maioria dos aplicativos não precisa de nada além do que o acesso normal oferece. Porém, às vezes é necessário um acesso privilegiado para podermos utilizar certas APIs. Quando criamos um aplicativo privilegiado e enviamos ele ao Firefox Marketplace o processo de aprovação é mais rigoroso (e isso é bom).
Durante o desenvolvimento, é possível acessarmos APIs privilegiadas sem precisarmos de nenhuma permissão especial da Mozilla. Porém quando vamos distribuir um app privilegiado precisamos primeiro enviá-lo ao Firefox Marketplace. Lá ele passará por uma revisão de código e um rigoroso processo de aprovação. Se estiver tudo ok, ele será assinado digitalmente e estará pronto para distribuição. Isso é bom pois usuário tem a certeza que aplicativos que acessam APIs mais sensíveis do telefone são verificados para garantir sua privacidade e segurança.
Na página sobre as WebAPIs no wiki da Mozilla podemos ver quais APIs estão implementadas em quais plataformas e qual o nível de acesso necessário para utilizá-las.

Níveis de acesso para cada API
Como podemos ver na imagem acima, o acesso à Geolocation API está disponível para todos os aplicativos, enquanto a API Device Storage API está disponível somente para aplicativos privilegiados.
As WebAPIs
No Firefox OS não precisamos de nada além das tecnologias web para construir apps tão capazes quanto os apps nativos das outras plataformas. Toda a parte de acesso ao hardware é realizada através das WebAPIs. Para conhecer a lista de APIs disponíveis para a versão atual do Firefox OS basta visitar a página sobre as WebAPIs no wiki da Mozilla.
Para ilustrar quão fáceis são essas APIs vou mostrar alguns exemplos de uso a seguir.
Exemplo #1: Realizar ligações
Imaginemos que você tem um programa que precisa abrir o discador do telefone com um número preenchido. Basta utilizar o código abaixo:
Enviando um número para o telefone
1 var call = new MozActivity({
2 name: "dial",
3 data: {
4 number: "5555-9999"
5 }
6 });
Esse código apenas abre o discador com o número preenchido, portanto o usuário do telefone precisa apertar o botão de discar para efetuar a ligação. Esse tipo de API, que precisa de uma ação do usuário antes de executar sua função, é bem comum e é oferece uma forma de segurança, afinal, utilizando essa API você não tem como criar um programa que liga para algum lugar sem a aprovação do usuário. Outras APIs que são capazes de efetuar ligações sem a confirmacão do usuário estão disponíveis para níveis mais elevados de aplicativos. A API do exemplo está disponível para todos os aplicativos.
Essa API é uma Web Activity. Para saber mais sobre esse tipo de API visite este artigo no blog da Mozilla.
Exemplo #2: Salvar um contato
Salvando um contato
1 var contact = new mozContact();
2 contact.init({name: "Odin"});
3
4 var request = navigator.mozContacts.save(contact);
5 request.onsuccess = function() {
6 // contato salvo com sucesso
7 };
8 request.onerror = function() {
9 // não foi possível salvar o contato
10 };
Essa API cria um objeto com os dados do contato e salva ele na agenda do telefone, sem interferência do usuário, e está disponível somente para aplicativos privilegiados. Esse padrão, onde se cria um objeto com um callback de sucesso e um de erro, é muito utilizado nas WebAPIs.
Para saber mais sobre a API de contatos, visite a pagina da Contacts API no wiki da Mozilla.
Exemplo #3: Pegando uma imagem da camera
Pegando uma imagem
1 var getphoto = new MozActivity({
2 name: "pick",
3 data: {
4 type: ["image/png", "image/jpg", "image/jpeg"]
5 }
6 });
7
8 getphoto.onsuccess = function () {
9 var img = document.createElement("img");
10 if (this.result.blob.type.indexOf("image") != -1) {
11 img.src = window.URL.createObjectURL(this.result.blob);
12 }
13 };
14
15 getphoto.onerror = function () {
16 // erro!
17 };
Aqui vemos mais um exemplo de uma WebActivity (falaremos de web activities mais adiante no livro). As Web Activities estão disponíveis para todos os aplicativos. No caso desse exemplo, utilizamos uma atividade do tipo pick e passamos os MIME Types desejados. Ao executar esse código, o sistema mostra uma tela para o usuário pedindo para ele selecionar da onde a imagem deve vir (câmera, álbum, wallpapers) e caso o usuário selecione uma imagem a callback de sucesso é executada, caso ele cancele a ação a callback de erro é executada. No caso de sucesso, o programa recebe um blob com a imagem. Na imagem abaixo podemos ver um exemplo do workflow:

Exemplo da atividade pick
Conclusão
Nesse capítulo vimos que diferentemente de páginas web normais, os aplicativos hospedados e empacotados do Firefox OS precisam de um arquivo de manifesto para se tornarem apps. Vimos também que do ponto de vista da segurança, apps empacotados podem ser normais, privilegiados ou certificados. Somente apps privilegiados ou certificados podem acessar as WebAPIs mais poderosas disponíveis no sistema.
Agora é hora de colocar a mão na massa e fazermos um app!