Configuração de rotação automática com base no estado do dispositivo

Em dispositivos dobráveis, a experiência do usuário pode ser otimizada adaptando o comportamento de rotação da tela ao estado físico do dispositivo. Por exemplo, você pode definir que a tela gire automaticamente quando o dispositivo for aberto em uma postura semelhante a um tablet, mas fique bloqueada no modo retrato quando o dispositivo estiver dobrado.

A partir do Android 13, é possível personalizar as configurações de rotação automática com base nos estados do dispositivo, como dobrado, desdobrado ou semidobrado (modo de mesa).

Página de configurações de rotação automática com base no estado do dispositivo

Figura 1:configurações de rotação automática com base no estado do dispositivo, conforme visto pelo usuário.

Ativar a configuração de rotação automática com base no estado do dispositivo

Para ativar e configurar a rotação automática com base no estado do dispositivo, crie uma sobreposição de dispositivo para o arquivo config.xml do framework, da seguinte maneira:

  1. Configure o comportamento padrão de rotação automática para diferentes posturas do dispositivo preenchendo a matriz de números inteiros config_perDeviceStateRotationLockDefaults na sobreposição config.xml do dispositivo:

    <!-- In your device overlay, for example,
        device/generic/goldfish/phone/overlay/frameworks/base/core/res/res/values/config.xml -->
    <resources>
        <!-- Map of device posture to rotation lock setting. Each entry must be
            in the format "key:value", or "key:value:fallback_key" for example:
            "0:1" or "2:0:1". The keys are one of
            Settings.Secure.DeviceStateRotationLockKey, and the values are one of
            Settings.Secure.DeviceStateRotationLockSetting. -->
        <integer-array name="config_perDeviceStateRotationLockDefaults">
            <item>0:1</item> <!-- CLOSED -> LOCKED -->
            <item>1:0:2</item> <!-- HALF_OPENED -> IGNORED and fallback to
                device posture OPENED -->
            <item>2:2</item> <!-- OPENED -> UNLOCKED -->
            <item>3:0:0</item> <!-- REAR_DISPLAY -> IGNORED and fallback to
                device posture CLOSED -->
        </integer-array>
    </resources>
    

    fallback-key é uma referência a outra posição do dispositivo, e você precisa especificar quando o valor de uma posição é Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED. Quando uma postura é configurada dessa forma, todas as solicitações para receber ou definir a preferência de rotação automática são redirecionadas para a postura alternativa.

    Por exemplo, se a postura HALF_OPENED voltar para a postura OPENED:

    • A leitura da configuração de rotação automática para HALF_OPENED retorna a configuração atual de OPENED.
    • Escrever uma nova preferência de rotação automática enquanto o dispositivo está HALF_OPENED atualiza a preferência para a postura OPENED.
  2. Configure descrições para cada postura de dispositivo definível pelo usuário. Preencha a matriz de strings config_settableAutoRotationDeviceStatesDescriptions na sobreposição do app Configurações do dispositivo:

    <!-- In your device's Settings app overlay -->
    <resources>
        <!-- The settings/preference description for each settable device
            posture defined in the array
            "config_perDeviceStateRotationLockDefaults".
            The item in position "i" describes the auto-rotation setting for the
            device posture also in position "i" in the array
            "config_perDeviceStateRotationLockDefaults". -->
        <string-array name="config_settableAutoRotationDeviceStatesDescriptions">
            <item>Auto-rotate when folded</item>
            <item>@null</item> <!-- No description for state in position 1 (it
            is not settable by the user) -->
            <item>Auto-rotate when unfolded</item>
        </string-array>
    </resources>
    
  3. Use as APIs corretas para modificar essas configurações de maneira programática, em vez de gravar diretamente nos provedores de configurações, para evitar comportamentos inconsistentes:

    • Para mudar o estado atual de bloqueio de rotação (modifica ACCELEROMETER_ROTATION):

    • Para mudar a preferência de bloqueio de rotação para um estado específico do dispositivo (modifica DEVICE_STATE_ROTATION_LOCK):

Detalhes da implementação

As configurações e as principais classes que controlam o comportamento de rotação automática em um dispositivo dobrável são descritas nas seções a seguir.

Configurações

O sistema usa as duas configurações a seguir para gerenciar a rotação automática:

  • Settings.System.ACCELEROMETER_ROTATION: essa é a principal configuração de rotação automática. Para um dispositivo dobrável, o valor reflete se a rotação automática está ativada para a postura atual do dispositivo.

  • Settings.Secure.DEVICE_STATE_ROTATION_LOCK: essa configuração armazena a preferência de rotação automática do usuário para cada postura do dispositivo (por exemplo, dobrado ou desdobrado). Isso permite que o sistema aplique a preferência correta quando a postura do dispositivo muda.

    A configuração é armazenada como uma string delimitada por dois-pontos. Cada par de valores representa uma postura do dispositivo e a configuração de rotação correspondente. O formato é:

    <device_posture_0>:<rotation_value_0>:<device_posture_1>:<rotation_value_1>...

    Os valores de rotação são:

    • 0: ignorado. A configuração de uma postura alternativa é usada.
    • 1: bloqueado (o giro automático está desativado)
    • 2: desbloqueado (a rotação automática está ativada)

    Por exemplo, a string "0:2:2:1" significa:

    • No estado dobrado (postura 0), o giro automático fica desbloqueado (2).
    • Para o estado desdobrado (postura 2), o giro automático fica bloqueado (1).

Classes principais

A lógica para gerenciar as configurações de rotação automática com base no estado do dispositivo é processada pelas seguintes classes:

  • DeviceStateAutoRotateSettingManagerImpl:gerencia a configuração DEVICE_STATE_ROTATION_LOCK. Ele oferece métodos para atualizar a configuração, recuperar o valor dela e registrar listeners para mudanças.

  • DeviceStateAutoRotateSettingController (gerenciador de janelas):sincroniza ACCELEROMETER_ROTATION e DEVICE_STATE_ROTATION_LOCK. Quando a postura do dispositivo muda, ele atualiza ACCELEROMETER_ROTATION com base na preferência do usuário para o novo estado. Ele garante que qualquer mudança em ACCELEROMETER_ROTATION seja salva de volta em DEVICE_STATE_ROTATION_LOCK para a posição atual do dispositivo. Da mesma forma, as mudanças em DEVICE_STATE_ROTATION_LOCK para a posição atual são refletidas em ACCELEROMETER_ROTATION.

  • DeviceStateAutoRotateSettingController (app Configurações):controle a interface na página de configurações de rotação automática baseada no estado do dispositivo.

  • PostureDeviceStateConverter: converte entre identificadores genéricos de estado do dispositivo e os identificadores de posição do dispositivo usados por esse recurso.

Validação

Como o comportamento desse recurso depende muito da configuração do OEM, não há testes específicos do CTS para ele. É necessário fazer testes manuais para verificar se as configurações de rotação automática mudam conforme o esperado quando o dispositivo transiciona entre os diferentes estados físicos que você configurou.