Gerenciamento de Janelas

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() ou window.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 sistema
  • portrait: força a tela a ser renderizada em retrato 
  • landscape: 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 atual
  • runningApps / numRunningApps — o conjunto de apps em execução
  • openFrame / 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.  

Veja também

 De navegador para navegador

Etiquetas do documento e colaboradores

 Colaboradores desta página: chrisdavidmills, jwhitlock, PriscillaAlcalde
 Última atualização por: chrisdavidmills,