Em geral, um gerenciador de janelas (ou window management) é a parte de um aplicativo que controla o posicionamento e aparência das janelas em uma interface gráfica de usuário. Este artigo analisa a forma como o Firefox OS lida com o Gerenciamento de Janelas.
No Firefox OS, o Gerenciamento de Janelas é parte do app do sistema, que é responsável por:
- Ciclo de vida do app e interação entre aplicativos
- Layout, redimensionamento, orientação, visibilidade e animação / transições de elementos de interface do usuário.
- Lógica UI de todo o sistema, tais como atividades na web, notificações de aplicativos, e gerenciador de tarefas.
- UI características específicas de cada aplicação, tais como pop-ups, menus de contexto, e páginas de erro.
Antes de mergulharmos em detalhes de tais itens, vamos ver como os aplicativos são lançados em Gaia.
Como os aplicativos são lançados em Gaia
Um aplicativo pode ser lançado em Firefox OS em diversas maneiras, por exemplo, através de uma mensagem do sistema criada por outro aplicativo, ou através de um clique no ícone na tela inicial.
Os eventos que controlam a abertura das aplicações são tratadas pelo motor gecko e Sistema APP, que será explicado em mais detalhes abaixo.
Estrutura do App
Todos os aplicativos webapps Gaia são apps empacotados, eles são essencialmente arquivos zip contendo todos os ativos do aplicativo: HTML, CSS, JavaScript, imagens, manifesto etc. Cada webapp em Gaia é organizado seguindo a seguinte estrutura básica:
apps
/
[
app
name
]
/
-
js
-
styles
-
locales
-
test
-
index
.
html
-
manifest
.
webapp
Quando um dos aplicativos Gaia built-in for iniciado a partir da tela inicial, Gecko tentará abrir um URL de manifest://[app name].gaiamobile.org:8080
, analisando manifest.webapp
at that location, e então rodando o arquivo index definido no manifesto launch_path
— which is index.html
para todos os webapps built-in. O arquivo index.html
vai puxar todos os estilos e JavaScript necessários.
Nota: Como uma convenção informal, o principal ponto de entrada JavaScript para aplicativos Gaia é geralmente [app name].js
ou main.js.
Seqüência de lançamento do App
Os eventos são enviados para o Gecko. Uma vez que o Gecko está pronto, a AppwindowFactory
do system/js/app_window_factory.js irá receber um evento de lançamento webapps-launch
para um app, ou um evento open-app
para lidar com uma mensagem do sistema pendente.
window.addEventListener('applicationready', function appReady(e) { window.removeEventListener('applicationready', appReady); window.addEventListener('webapps-launch', self); window.addEventListener('webapps-close', self); window.addEventListener('open-app', self); });
Para detalhes sobre a sessão handleEvent, o this.launch(config)
irá lançar uma janela app ou uma atividade. Uma vez que o app é fechado, a Appwindow
receberá o evento webapps-close
.
O processo principal no método launch()
é:
var app = AppWindowManager.getApp(config.origin); if (app) { app.reviveBrowser(); } else if (config.origin !== homescreenLauncher.origin) { new AppWindow(config); } else if (config.origin == homescreenLauncher.origin) { homescreenLauncher.getHomescreen().ensure(); }
Primeiro o código verifica se a variável app existe e tenta reanimá-lo no Gecko. Por outro lado, se é um app normal, criamos uma instância AppWindow
para o app. O outro caso especial é o homescreenLauncher
- neste caso, fazemos as operações necessárias.
AppWindow
O Firefox OS utiliza uma API mozBrowser especial para fazer com que uma web page se comporte como um app. A raíz do Gerenciamento de Janelas é apenas um invólucro API mozBrowser para lidar com iFrames interiores (da janela). Um iFrame especial do tipo moz-browser é criado para tornar o ato iFrame como uma janela do navegador real.
A AppWindow
cria, contém e gerencia um mozBrowser
iFrame. A AppWindow
vai manipular todos os eventos mozBrowser
disparados a partir do próprio iFrame mozBrowser
e mostrar as características de interface do usuário relevantes.
Ciclo de gerenciamento de vida do App
O ciclo de vida completo de um app é o seguinte:
- Lançamento do App
- Anexa o iframe para o System DOM tree
- Inicia o App com animação de abertura
- O App é aberto
- O App fecha a animação
- O App é fechado
- Remove o iframe do DOM tree
- O App é encerrado
Lançando apps
Quando um usuário toca nos ícones na tela inicial, a tela inicial usa a mozApps API para notificar o motor Gecko para abrir o aplicativo correspondente. Quando Gecko está pronto, ele irá enviar o evento apropriado para aplicação do sistema
Eliminando apps
Aplicativos serão eliminados nas seguintes circunstâncias:
- Um app falha
- O OOM killer o elimina
- O app é fechado via Gerenciador de Tarefas
O window.close()
é chamado
Para aplicativos ativos, após a animação de encerramento, o iFrame do app eliminado é retirado do DOM tree. Para aplicativos inativos, o iframe é removido imediatamente após ser eliminado.
Os apps serão interrompidos nas seguintes circunstâncias:
- Para as atividades web: quando o chamador de atividade é aberto
- Popups: quando o chamador window.open é aberto
- App: nada a ver
Relançando apps
Os Apps serão relançados nas seguintes circunstâncias:
- homescreen app: Quando o botão home é pressionado
- Os aplicativos zombie são ressucitados com o mesmo URL, se aberto a partir do Gerenciador de Tarefas ou fraudado em um gesto de borda. (Recurso Experimental)
Como o app é renderizado
Quando nós lançamos um app, a tela será renderizada com os seguintes blocos:
- Header do sistema
- iframe do App
- Barra de invólucro inferior (se estiver no browser chrome)
Layout do App
O principal recipiente do iframe do aplicativo é o seguinte:
<iframe id="browser2" mozallowfullscreen="true" mozbrowser="true" remote="true"... ... src="", data-url="" data-frame-type="window" data-frame-origin="..."> </iframe>
O iframe contém:
- Caminho de inicialização (
data-url
,data-frame-origin
) - Atributos iframe mozbrowser (
mozallowfullscreen="true"
,mozbrowser="true"
) - Recipiente, sobreposição, UI específica do app
Redimensionando o AppWindow
O AppWindow será redimensionado em várias situações:
- O sistema app não será redimensionado até que as mudanças de orientação sejam feitas
- Para aplicações gerais, o redimensionamento ocorre quando:
- O app do sistema é redimensionado
- O teclado de animação abertura/fechamento termina
- A barra de status muda
window.resizedBy()
ouwindow.resizeTo()
é chamado- O botão home do software é alternado
Em resumo, o tamanho da janela é afetado pelo:
- Estado da orientação
- Estado do teclado
- Estado do AttentionScreen (possui ligação, possui mensagem etc.)
- Estado de navegação do Chrome
- Estado de tela cheia
manifest.fullscreen
/parentWindow
- Estado do homebutton do software
Orientação da AppWindow
A orientação de aplicativos pode ser controlada a partir de cada aplicativo individual ou globalmente pelo sistema. Você pode definir a orientação no arquivo manifest.webapp
do aplicativo com a propriedade de orientação, por exemplo:
"orientation": "default",
Você também é capaz de usar a API de orientação para bloquear ou desbloquear a orientação:
screen.mozLockOrientation([‘portrait-primary’]); screen.mozUnlockOrientation();
Existem vários valores de parâmetros que podem ser utilizados para forçar a orientação:
default
: orientação padrão do sistemaportrait
: força a tela a ser renderizada em retratolandscape
: força a tela a ser renderizada em paisagem
Mais detalhes estão disponíveis na referência Screen.lockOrientation, e você pode ver um exemplo em gaia/dev_apps/uitest/js/API/orientation.js.
Visibilidade do App
O app do sistema vai para o segundo plano apenas quando a tela está desligada, enquanto aplicativos normais vão para o segundo plano dependendo de alguns fatores:
- Competição de audio
- Política de processo
- Renderização
Nota: A visibilidade da página é herdada enquanto o iframe pai está inativo.
Os apps estão sempre em primeiro plano quando:
- Animações de abertura começam
- Animações swipe-in animation terminam
- A tela é desbloqueada
Os app estão sempre no segundo plano quando:
- A animação de fechamento termina
- 3 segundos após uma tela de chamado torna-se visível
- A tela é desligada
Existem algumas exeções para as regras acima:
- App ativo com reprodução de áudio no canal normal
- Apps chamando atividades web em linha
- Apps abrindo
window.open('', '', 'dialog')
Animação e transição da AppWindow
O Gerenciador de Janelas Gaia também proporciona uma animação app e transições para uma experiência do usuário mais suave.
A animação e as transições AppWindow são gerenciadas pelas seguintes estatísticas:
displayedApp
— o app atualrunningApps
/numRunningApps
— o conjunto de apps em execuçãoopenFrame
/closeFrame
— o quadro de transição para abertura/fechamento de animações
Ao chamar o método setDisplayedApp()
, o aplicativo será lançado via estatísticas ilustradas pelo diagrama a seguir.
Existem vários truques envolvidos no controle do fluxo de animação do app do Firefox OS:
- Antes de um aplicativo ser aberto, nós precisamos de assegurar que ele esteja recuperado de seu plano de fundo. Costumamos ter uma imagem de tela 1x1 para forçar o redesenho.
- Depois que o app está pronto para ser aberto, rodamos a animação de abertura do próximo app e a animação de fechamento do app atual ao mesmo tempo.
- Rodamos o código para bloquear/desbloquear as orientações da tela, ambos durante a abertura e o fechamento do app.
- Realizamos um redimensionamento na abertura somente se o app é redimensionado uma vez. Caso contrário, ignoramos esta etapa de redimensionamento.
- Nós mudamos a visibilidade da página, tirando novamente um screenshot 1x1 (veja acima).
UI específica da AppWindow
Existem vários elementos de interface do usuário que são relevantes apenas para determinadas aplicações, tais como o browser Chrome, diálogos modais, menus de contexto e páginas de erro.
Vamos discutir alguns deles.
Diálogos modais
No desktop Firefox, se você abrir o console de desenvolvedor em seu navegador e digitar comandos como alert()
, confirm()
, e prompt()
, você irá visualizar um diálogo centrado na tela que bloqueia o conteúdo subjacente. O equivalente no Firefox OS são os diálogos modais.
Diálogos de menu contextuais
Os menus de contexto (ou long press menus) são conceitos familiares para os desenvolvedores mobile. Em geral, no design de apps, as ações utilizadas com mais freqüência devem estar visíveis para os usuários de modo que eles possam controlar o aplicativo facilmente. Menus contextuais fornecem um lugar para conter ações que não cabem na interface imediata do usuário, mas ainda deve estar facilmente disponível.
Diálogo de autenticação (https)
Definido em system/js/app_authentication_dialog.js.
Seletor de valor, tempo, diálogos de data
Definido em system/js/value_selector/.
Diálogos de permissões
Definido em system/js/permission_manager.js e system/js/media_recording.js (para o painel de bandeja utilitário).
Apps especiais
Alguns aplicativos necessitam de um objeto especial appWindow
para lidar com funcionalidades especiais que eles contenham. Exemplos incluem:
- Tela inicial
- FTU
- Teclado
- Controle de custo
- Câmera de segurança
- Bloqueio de tela
Gerenciamento de janela filha
Janelas de aplicativos filha são abertas diretamente ou indiretamente por outros aplicativos/páginas. Alguns exemplos são:
- Janela de atenção
- Janela PopUp
- Janela de atividade
- UI Confiável / janela confiável
Quando uma janela filha termina normalmente, sua janela pai deverá ser reaberta. Algum tipo de janela filha também pode ter outra janela filha. A gestão do processo de gestão entre janelas pai e filho é um problema.
Janela de atenção
Janelas de atenção são utilizadas para obter sua atenção:
- Tela de chamada - dialer
- Tela de alarme - relógio
- Confirmações de permissão
Atualmente as janela de atenção são forçadas para uma orientação padrão (retrato primário).
UI confiável
Persona e a API mozPay são UI confiáveis. Elas utilizam um dimensionamento específico: 80%. A tela inicial é parcialmente visível durante o tempo em que a UI confiável está em execução.
Gerenciamento de histórico
Nesta seção, vamos olhar para alguns dos componentes que lidam com a gestão do histórico no Firefox OS.
Gerenciador de tarefas
O Gerenciador de Tarefas (vista do cartão) pode ser acionado por um toque longo do botão home. Ele mostra a história do app no dispositivo, e é capaz de eliminar ativamente um aplicativo.
No Firefox OS versão 2.0, há um recurso experimental disponível para manter aplicativos zumbis presentes e fingir que eles ainda estão vivos.
Disposições de atividades Web
Atividades inline criam uma nova página de referência para fornecer os dados para a atividade.
Atividades de janela irão reutilizar a janela de aplicativo existente para consumir os dados da atividade.
Gestos de Borda (experimental)
O recurso de gesto de Borda experimental está disponível no modo de desenvolvedor no Firefox OS 2.0+, e permite que você utilize um simples arraste de dedo da direita para a esquerda a partir da borda do dispositivo para navegar entre aplicativos e páginas da web.
Como é escolhido o próximo aplicativo para exibição?
- Janela filha do aplicativo ativo
- O tempo de lançamento é mais recente
- Encontrar a janela guia do próximo app stack
Como o app anterior é escolhido?
- Parent window of the active app
- Launch time is older
- Find the rear window of the previous app stack
Gestão de captura de tela
A ferramenta de captura de tela é usada pelo gerenciador de tarefas (exibição do cartão) para mostrar como os apps aparecem no histórico. Uma captura de tela do app é tirada quando a animação de fechamento termina.