Picture-in-picture

O recurso picture-in-picture (PIP) para dispositivos portáteis Android permite que os usuários redimensionem um app com uma atividade em andamento para exibição em uma janela pequena. O PIP é especialmente útil para apps de vídeo, porque o conteúdo continua sendo reproduzido enquanto o usuário pode realizar outras ações. Os usuários podem manipular a posição dessa janela pela SystemUI e interagir com o aplicativo que está no modo picture-in-picture com até três ações fornecidas pelo app.

O PIP exige a permissão explícita dos aplicativos que o oferecem e funciona por atividade. Um único aplicativo pode ter várias atividades, mas apenas uma delas está no modo PIP. As atividades solicitam a entrada no modo picture-in-picture chamando enterPictureInPictureMode() e recebem callbacks de atividade na forma de onPictureInPictureModeChanged().

O método setPictureInPictureParams() permite que as atividades controlem a proporção durante o PIP e ações personalizadas, que permitem que os usuários interajam com a atividade sem precisar expandi-la. No PIP, a atividade está em um estado pausado, mas de renderização, e não recebe diretamente a entrada de toque ou o foco da janela. Apenas uma tarefa pode estar no PIP por vez.

Mais informações estão disponíveis na documentação do modo picture-in-picture para desenvolvedores Android.

Requisitos do dispositivo

Para oferecer suporte ao PIP, ative o recurso do sistema PackageManager#FEATURE_PICTURE_IN_PICTURE em /android/frameworks/base/core/java/android/content/pm/PackageManager.java. Os dispositivos que oferecem suporte ao PIP precisam ter uma tela maior que 220 dp na menor largura. Semelhante à tela dividida com várias janelas, o PIP permite que várias atividades sejam executadas na tela ao mesmo tempo. Portanto, os dispositivos precisam ter CPU e RAM suficientes para oferecer suporte a esse caso de uso.

Implementação

A maior parte do gerenciamento do ciclo de vida da atividade é feita no sistema entre ActivityManager e WindowManager. A implementação da interface de referência está no SystemUI pacote.

As modificações no sistema não podem afetar o comportamento intrínseco dele, conforme definido pelos testes do conjunto de testes de compatibilidade (CTS, na sigla em inglês). A lógica do sistema para PIP gira principalmente em torno do gerenciamento de tarefas e atividades na pilha "fixada". Confira uma visão geral rápida da classe:

  • ActivityRecord: rastreia o estado picture-in-picture de cada atividade. Para impedir que os usuários entrem no PIP em determinadas circunstâncias, como na tela de bloqueio ou durante a RV, adicione casos a checkEnterPictureInPictureState().
  • ActivityManagerService: a interface principal da atividade para solicitar a entrada no PIP e a interface para chamadas de WindowManager e SystemUI para mudar o estado da atividade do PIP.
  • ActivityStackSupervisor: chamado do ActivityManagerService para mover tarefas para dentro ou para fora da pilha fixada, atualizando o WindowManager conforme necessário.
  • PinnedStackWindowController: a WindowManager interface do ActivityManager.
  • PinnedStackController: informa mudanças no sistema para SystemUI, como IME mostrado/oculto, proporção alterada ou ações alteradas.
  • BoundsAnimationController: anima as janelas de atividade do PIP de uma maneira que não aciona uma mudança de configuração durante o redimensionamento.
  • PipSnapAlgorithm: uma classe compartilhada usada no sistema e na SystemUI que controla o comportamento de ajuste da janela do PIP perto das bordas da tela.

A referência SystemUI oferece uma implementação completa do PIP que oferece suporte à apresentação de ações personalizadas aos usuários e à manipulação geral, como expansão e dispensa. Os fabricantes de dispositivos podem aproveitar essas mudanças, desde que elas não afetem os comportamentos intrínsecos definidos pelo CDD. Confira uma visão geral rápida da classe:

  • PipManager: o componente que é iniciado com SystemUI.SystemUI
  • PipTouchHandler: o gerenciador de toques, que controla os gestos que manipulam o PIP. Ele só é usado enquanto o consumidor de entrada do PIP está ativo (consulte InputConsumerController). Novos gestos podem ser adicionados aqui.
  • PipMotionHelper: uma classe de conveniência que rastreia a posição do PIP e a região permitida na tela. Faz chamadas para ActivityManagerService para atualizar ou animar a posição e o tamanho do PIP.
  • PipMenuActivityController: inicia uma atividade que mostra as ações fornecidas pela atividade que está no PIP. Essa atividade é uma atividade de sobreposição de tarefas e remove o consumidor de entrada sobreposto para permitir que ele seja interativo.
  • PipMenuActivity: a implementação para a atividade de menu.
  • PipMediaController: o listener que atualiza SystemUI quando a sessão de mídia muda de uma maneira que pode afetar as ações padrão no PIP.
  • PipNotificationController: o controlador que garante que uma notificação esteja ativa enquanto um usuário estiver usando o recurso PIP.
  • PipDismissViewController: a sobreposição mostrada aos usuários quando eles começam a interagir com o PIP para indicar que ele pode ser dispensado.

Posicionamento padrão

Há vários recursos do sistema que controlam o posicionamento padrão do PIP:

  • config_defaultPictureInPictureGravity: o número inteiro de gravidade, que controla o canto para colocar o PIP, como BOTTOM|RIGHT.
  • config_defaultPictureInPictureScreenEdgeInsets: : os deslocamentos das laterais da tela para posicionar o PIP.
  • config_pictureInPictureDefaultSizePercent e config_pictureInPictureDefaultAspectRatio: a combinação da porcentagem da largura da tela e a proporção controla o tamanho do PIP. O tamanho padrão calculado do PIP não pode ser menor que @dimen/default_minimal_size_pip_resizable_task, conforme definido pelo CTS e pelo CDD.
  • config_pictureInPictureSnapMode: o comportamento de ajuste, conforme definido em PipSnapAlgorithm.

As implementações de dispositivos não podem mudar as proporções mínima e máxima definidas no CDD e no CTS.

Permissões

A "operação de aplicativo" por pacote (OP_PICTURE_IN_PICTURE) em AppOpsManager (main/core/java/android/app/AppOpsManager.java) permite que os usuários controlem o PIP por aplicativo nas configurações do sistema. As implementações de dispositivos precisam respeitar essa verificação quando uma atividade solicita a entrada no modo picture-in-picture.

Teste

Para testar implementações de PIP, execute todos os testes relacionados ao picture-in-picture encontrados em testes do CTS do host em /cts/hostsidetests/services/activitymanager, principalmente em ActivityManagerPinnedStackTests.java.