Sugestões de rotação

No Android 8.0, os usuários podiam alternar entre os modos de rotação automática e rotação retrato usando um Bloco de Configurações rápidas ou as configurações de exibição. No Android 9, atualizamos o modo de rotação de retrato para eliminar rotações involuntárias fixando a rotação da tela atual, mesmo que a posição do dispositivo mude. Os usuários podem acionar a rotação manualmente quando necessário pressionando um novo botão na barra de navegação. Renomeamos o modo retrato para "Bloqueio de rotação", que é ativado quando o giro automático está desativado. Não há mudanças no modo de giro automático.

Quando o dispositivo está no modo de bloqueio de rotação, os usuários podem bloquear a tela para qualquer rotação compatível com a atividade visível na parte de cima (considerando as restrições atual do sistema). Se a atividade principal puder ser renderizada em várias rotações no modo de rotação automática, as mesmas opções estarão disponíveis no modo de rotação bloqueada, com algumas exceções com base na configuração screenOrientation da atividade.

O modo de bloqueio de rotação funciona mostrando um botão na barra de navegação nas mudanças de rotação do dispositivo. Para fazer isso, o sensor de orientação do dispositivo precisa permanecer ativo, mesmo quando a rotação automática estiver desativada. Tocar nesse botão define a preferência de rotação do usuário (Settings.System.USER_ROTATION). O WindowManager usa essa preferência, junto com outros detalhes sobre a atividade principal e o status do sistema, para mudar a rotação do sistema. O WindowManager continua usando a preferência de rotação do usuário ao decidir em qual rotação renderizar o sistema ao passar para outra atividade.

Este GIF mostra um smartphone na orientação paisagem com a tela na
       orientação retrato. Um ícone aparece para perguntar ao usuário se ele quer
       mudar a orientação da tela para paisagem.
Figura 1. Botão de sugestão de rotação com o gesto "Deslizar o botão home para cima" ativado

A preferência de rotação do usuário precisa ser mantida ao alternar entre atividades. No entanto, como a maioria dos usuários de smartphones só quer usar o modo paisagem por um período curto e temporário, adicionamos o viés de orientação natural. A preferência de rotação do usuário é redefinida para a orientação natural do dispositivo sempre que a rotação do sistema muda para a orientação natural do dispositivo. Para a maioria dos smartphones, a orientação natural do dispositivo é retrato (0º). A redefinição da preferência de rotação do usuário geralmente acontece ao usar um app somente em modo retrato, bloquear o smartphone ou voltar ao espaço de trabalho da tela de início.

As interações de rotação para os usuários não mudaram muito na última década. Os usuários podem ter dificuldade para descobrir esse recurso devido ao histórico anterior de rotação e posicionamento de botões na barra de navegação. Por esse motivo, adicionamos um modo de introdução ao botão de rotação que destaca o botão quando ele aparece. O comportamento do modo de introdução só acontece nas primeiras interações com o botão, depois que o modo de introdução é desativado.

Origem

O suporte a sugestões de rotação foi adicionado ao Android 9. A maioria das mudanças está contida nos seguintes arquivos.

  • services/.../server/policy/PhoneWindowManager.java:
    • Hooks que consomem a saída de WindowOrientationListener (MyOrientationListener, responsável por monitorar sensores para determinar se o dispositivo foi girado)
    • Mantém o WindowOrientationListener ativo mesmo quando a rotação automática está desativada (consulte needSensorRunningLp()).
    • Calcula a rotação do sistema de acordo com a preferência de rotação do usuário, as configurações screenOrientation da atividade principal e o status do sistema (consulte rotationForOrientationLw()).
    • Determine se a atividade principal pode girar para uma determinada rotação (consulte isRotationChoicePossible()).
  • SystemUI/.../statusbar/phone/NavigationBarFragment:
    • Determina se o botão da barra de navegação precisa ser mostrado em callbacks de sugestão de rotação de PhoneWindowManager (consulte onRotationProposal()).
    • Processa quando ocultar o botão da barra de navegação de rotação (consulte as chamadas para setRotateSuggestionButtonState(false)).
    • Processa os tempos limite dos botões, incluindo o caso especial em que a navbar está oculta (geralmente em tela cheia)
    • Redefine a preferência do usuário ao retornar à orientação natural do dispositivo (mRotationWatcher).
    • Escolhe o estilo adequado para a animação do botão da barra de navegação, aplicada em NavigationBarView (consulte onRotationProposal()).
    • Adiciona a lógica do modo de apresentação, incluindo animação especializada (consulte as referências a Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED)
    • Implementa a flag de rotação disable2 (consulte disable()).
  • SystemUI/.../statusbar/phone/NavigationBarView.java:
    • A animação do ícone do botão de estilo foi estilizada para corresponder à rotação pendente (consulte updateRotateSuggestionButtonStyle()).
    • Processa mudanças na visibilidade do botão (confira setRotateButtonVisibility()), incluindo a lógica para ocultar o botão de rotação se determinados serviços de acessibilidade estiverem ativos (considerando a classificação da pilha de botões da barra de navegação mais à direita)
  • SystemUI/res/layout/menu_ime.xml:
    • Inclui um novo KeyButtonView para o botão de rotação, empilhado acima do menu e do seletor de IME/teclado, mas abaixo do botão "Acessibilidade"
  • SystemUI/res/drawable/ic_sysbar_rotate_button.xml:
    • AnimatedVectorDrawable complexo usado para animar o botão de navegação rotativo
    • O estilo (em SystemUI/res/values/styles.xml) é usado para definir os ângulos inicial e final da rotação para que o mesmo drawable possa ser usado para animar várias rotações iniciais e finais.
    • A cor do ícone é definida por TintedKeyButtonDrawable

Implementação

O Android 9 inclui todas as mudanças necessárias para que as sugestões de rotação funcionem em dispositivos que usam teclas de navegação de software (voltar, tela inicial etc.).

Os fabricantes de dispositivos que criam dispositivos com teclas de navegação de hardware que desejam implementar esse recurso precisam projetar e implementar o próprio affordance da IU do sistema ou desativar o recurso. É recomendável que qualquer superfície introduzida seja fácil de usar quando o dispositivo é mantido a 90º ou 180º em relação à rotação atual do sistema e seja acessível rapidamente. Por esses motivos, o uso de notificações (como é feito para o seletor de IME/teclado) não é recomendado.

Os requisitos de hardware para usar esse recurso são os mesmos para usar a rotação automática.

Para a consistência da implementação, é necessário que a preferência de rotação do usuário (Settings.System.USER_ROTATION) seja redefinida para a rotação natural do dispositivo quando o sistema muda para a rotação natural do dispositivo por qualquer motivo quando a rotação automática está desativada. A implementação fornecida faz isso (consulte NavigationBarFragment.mRotationWatcher).

Há uma nova flag em StatusBarManager.disable2 para impedir temporariamente que as sugestões de rotação apareçam. Consulte StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS. Essa flag precisa ser respeitada em todas as implementações, já que é usada por apps críticos do sistema, incluindo o Assistente de configuração. A implementação fornecida oferece suporte a isso (consulte NavigationBarFragment.disable()).

É altamente recomendável ativar o recurso e seguir a implementação do AOSP, se possível. Nosso objetivo é manter a experiência de rotação semelhante entre os dispositivos, refletindo a uniformidade da experiência na maioria dos smartphones entre a rotação automática e o bloqueio de retrato.

Personalização

Como as sugestões de rotação aparecem apenas no modo de rotação bloqueada (rotação automática desativada), é possível escolher se o recurso está ativado por padrão para novas instalações desativando a rotação automática por padrão. Consulte def_accelerometer_rotation em SettingsProvider/res/values/defaults.xml para fazer mudanças padrão.

Os usuários podem mudar facilmente se o giro automático está ativo ou não (independentemente do padrão) pelo bloco de rotação nas Configurações rápidas ou nas Configurações de exibição.

Validação

Para testes, o recurso pode ser ativado e desativado alterando um valor Settings.Secure de restrição. Isso é mais fácil de fazer executando o comando a seguir em uma instância privilegiada do adb:

adb shell settings put secure show_rotation_suggestions <x>

Defina x como 0 para desativar e 1 para ativar.

Para testes, o modo de introdução pode ser redefinido alterando o valor Settings.Secure associado. Isso é mais fácil de fazer executando o comando a seguir em uma instância privilegiada do adb:

adb shell settings put secure num_rotation_suggestions_accepted 0