Protocolo de dispositivo de interface humana (HID, na sigla em inglês) do monitor de posições da cabeça, disponível para dispositivos com o Android 13 e versões mais recentes, um dispositivo de rastreamento de cabeça seja conectado a um dispositivo Android por USB ou Bluetooth e ser exposto ao framework e aos apps do Android por meio do de sensores. Esse protocolo é usado para controlando um efeito de virtualizador de áudio (áudio 3D). Esta página usa os termos dispositivo e host no sentido de Bluetooth, em que device significa o dispositivo de rastreamento da cabeça e host significa o host do Android.
Os fabricantes de dispositivos precisam configurar seus dispositivos Android para ativar o suporte para protocolo HID do monitor de posições da cabeça. Para informações mais detalhadas sobre do Terraform, consulte a README de sensores dinâmicos (link em inglês).
Para acompanhar esta página, você precisa estar familiarizado com os seguintes recursos:
Estrutura de nível superior
O framework do Android identifica o rastreador de posições da cabeça como um dispositivo HID.
Para ver um exemplo completo de um descritor HID válido, consulte Apêndice 1: exemplo de um descritor HID
No nível superior, o rastreador da cabeça é uma coleção de aplicativos com o
Sensors
página (0x20
) e o uso de Other: Custom
(0xE1
). Dentro
são diversos campos de dados (entradas) e propriedades (recursos).
Propriedades e campos de dados
Esta seção descreve as propriedades e os campos de dados em um aplicativo de um rastreador de posições da cabeça.
Propriedade: descrição do sensor (0x0308
)
A propriedade de descrição do sensor (0x0308
) é uma string ASCII somente leitura (8 bits)
, que precisa conter os seguintes valores:
Versão 1.0 do monitor de posições da cabeça:
#AndroidHeadTracker#1.0
Versão 2.0 do monitor de posições da cabeça (disponível no Android 15 ou superior), o que inclui compatibilidade com LE Audio:
#AndroidHeadTracker#2.0#x
O x
é um número inteiro (1
, 2
, 3
) que indica o transporte de suporte:
- 1: ACL
- 2: ISO
- 3: ACL + ISO
Não é esperado um "null-terminator", o que significa que o tamanho total dessa propriedade tem 23 caracteres de 8 bits para a versão 1.0.
Essa propriedade serve como um discriminador para evitar colisões com outros com sensores personalizados.
Propriedade: ID exclusivo persistente (0x0302
)
A propriedade do ID exclusivo permanente (0x0302
) é uma matriz somente leitura de 16
, 8 bits cada (total de 128 bits). Nenhum terminador nulo é esperado. Isso
é opcional.
Essa propriedade permite dispositivos de rastreamento da cabeça integrados em áudio para fazer referência ao dispositivo de áudio ao qual estão conectados. Há suporte para os esquemas a seguir.
Rastreador de cabeça independente
Se a propriedade de ID exclusivo persistente (0x0302
) não existir ou estiver definida como "todos"
zeros, isso significa que o rastreador da cabeça não está permanentemente conectado a um
dispositivo de áudio e podem ser usados separadamente, por exemplo, permitindo que o usuário
associar manualmente o tracker principal a um dispositivo de áudio separado.
Referência usando endereço MAC do Bluetooth
Octeto | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Valor | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | B | T | MAC do Bluetooth |
Neste esquema, os primeiros 8 octetos precisam ser 0
, e os octetos 8 e 9 precisam conter
os valores ASCII B
e T
respectivamente e os seis octetos a seguir são
interpretado como um endereço MAC Bluetooth, supondo que o rastreador principal
se aplica a qualquer dispositivo de áudio que tenha esse endereço MAC. Esse endereço precisa ser
endereço MAC aleatório, mesmo se o dispositivo usar um endereço MAC aleatório para estabelecer
conexões de rede. Dispositivos dual modo conectados por Bluetooth clássico
(formato HID v1.0) e Bluetooth LE (formato HID v2.0) precisam expor dois HID
descritores com o mesmo endereço de identidade. Dispositivos de modo birregional com controles separados
os dispositivos esquerdo e direito precisam expor o Bluetooth LE HID usando o dispositivo duplo
em vez do dispositivo secundário somente LE.
Referência usando UUID
Sempre que o bit mais significativo (MSB) do octeto 8 for definido (≥0x80
), o campo
é interpretado como um UUID, conforme especificado em
RFC-4122. A
dispositivo de áudio correspondente fornece o mesmo UUID, que é registrado no
framework do Android, por meio de um mecanismo não especificado que é específico da
tipo de transporte usado.
Propriedade: estado do relatório (0x0316
)
O estado do relatório (0x0316
) é uma propriedade de leitura/gravação que tem o
semântica padrão, conforme definido na especificação HID. O host usa este
para indicar ao dispositivo quais eventos serão relatados. Somente os valores Não
Os eventos (0x0840
) e "Todos os eventos" (0x0841
) são usados.
O valor inicial desse campo precisa ser "No Events" e nunca deve ser modificado pelo dispositivo, apenas pelo host.
Propriedade: estado da energia (0x0319
)
A propriedade Estado de potência (0x0319
) é uma propriedade de leitura/gravação que tem o
semântica padrão, conforme definido na especificação HID. O host usa este
para indicar ao dispositivo em qual estado de energia ele deve estar. Somente o
Os valores Full Power (0x0851
) e Power Off (0x0855
) são usados.
O valor inicial deste campo é determinado pelo dispositivo e nunca deve ser modificado pelo dispositivo, apenas pelo host.
Propriedade: intervalo do relatório (0x030E
)
A propriedade Intervalo do relatório (0x030E
) é uma propriedade de leitura/gravação que tem o
semântica padrão, conforme definido na especificação HID. O host usa este
para indicar ao dispositivo com que frequência informar as leituras de dados.
As unidades são informadas em segundos. O intervalo válido para este valor é determinado pelo dispositivo
e são descritos usando o mecanismo
Mín./Máx. físico. Pelo menos 50 Hz
deve ser suportada, e a taxa máxima recomendada de relatórios é
100 Hz. Portanto, o intervalo mínimo do relatório precisa ser menor ou igual
a 20 ms e recomendamos que seja maior ou igual a 10 ms.
Propriedade: transporte LE reservado pelo fornecedor (0xF410
)
A propriedade do LE Transport reservada pelo fornecedor (0xF410
) é uma propriedade de leitura/gravação
que tem a semântica padrão, conforme definido na especificação HID. O organizador
usa essa propriedade para indicar o transporte selecionado (ACL ou ISO). Somente o
de valores ACL (0xF800
) e ISO (0xF801
) são usados, e ambos devem ser incluídos
na coleção lógica.
Essa propriedade é configurada antes dos estados de alimentação ou do relatório.
Campo de dados: valor personalizado 1 (0x0544
)
O campo "Valor personalizado 1" (0x0544
) é um campo de entrada usado para informar o
informações reais de rastreamento da cabeça. É uma matriz de 3 elementos, interpretada de acordo
às regras HID normais para valores físicos, conforme especificado na seção 6.2.2.7 do
a especificação HID. O intervalo válido para cada elemento é [-π, π] rad. Unidades
são sempre radianos.
Os elementos são interpretados como: [rx, ry, rz]
, de modo que [rx, ry, rz]
é uma
vetor de rotação,
que representa a transformação do frame de referência para o frame principal.
A magnitude precisa estar no intervalo [0..π].
O frame de referência é arbitrário, mas geralmente é fixo e precisa ser destro. Uma pequena quantidade de deslocamento é aceitável. Os eixos da cabeça são:
- X da orelha esquerda para a direita
- Y da parte de trás da cabeça até o nariz (de trás para a frente)
- Z do pescoço até o topo da cabeça
Campo de dados: valor personalizado 2 (0x0545
)
O campo "Valor personalizado 2" (0x0545
) é um campo de entrada usado para informar o
informações reais de rastreamento da cabeça. É uma matriz de ponto fixo de três elementos,
interpretado de acordo com as regras normais de HID para valores físicos.
As unidades são sempre radianos/segundo.
Os elementos são interpretados como: [vx, vy, vz]
, de modo que [vx, vy, vz]
é uma
vetor de rotação,
que representa a velocidade angular do frame da cabeça (em relação a si mesma).
Campo de dados: valor personalizado 3 (0x0546
)
O campo "Valor personalizado 3" (0x0546
) é um campo de entrada usado para rastreamento
descontinuidades no frame de referência. É um número inteiro escalar de 8 bits
tamanho. Deve ser incrementado (com encapsulamento) pelo dispositivo sempre que o
o frame de referência for alterado, por exemplo, se um algoritmo de filtro de orientação for alterado
usada para determinar se a orientação foi redefinida. Esse valor é
interpretado de acordo com as regras normais de HID para valores físicos. No entanto,
o valor físico e as unidades não importam. As únicas informações relevantes para
host é um valor alterado. Para evitar problemas numéricos relacionados à perda de precisão.
ao converter de unidades lógicas para físicas, é recomendável definir
valores para mínimo físico, máximo físico e expoente da unidade a zero neste campo.
Estrutura do relatório
O agrupamento de propriedades em relatórios (por atribuição dos IDs de relatório) é flexível. Para aumentar a eficiência, recomendamos separar as propriedades somente leitura das propriedades de leitura/gravação.
Para os campos de dados, os campos do valor personalizado 1, 2 e 3 devem estar no mesmo e estar em apenas um relatório para um determinado dispositivo (coleção de apps).
Enviar relatórios de entrada
O dispositivo precisa periodicamente e de modo assíncrono (por mensagens HID INPUT) enviar relatórios de entrada quando todas estas condições forem atendidas:
- A propriedade Estado de potência está definida como Potência total.
- A propriedade "Estado do relatório" está definida como "Todos os eventos".
- A propriedade Intervalo do relatório é diferente de zero.
A propriedade "Intervalo do relatório" determina a frequência de envio dos relatórios. Quando qualquer uma das condições acima não for atendida, o dispositivo não poderá enviar relatórios.
Compatibilidade com versões anteriores e anteriores
O protocolo HID do monitor de posições da cabeça usa um esquema de controle de versão que permite do Google, permitindo a interoperabilidade entre um host e um dispositivo que usa versões diferentes do protocolo. As versões do protocolo são identificadas por dois números, maior e menor, que têm semânticas distintas como descritos nas seções a seguir.
As versões com suporte em um dispositivo podem ser determinadas examinando-se
a propriedade "Descrição do sensor" (0x0308
).
Compatibilidade de versão secundária
As mudanças à versão secundária são compatíveis com versões anteriores. com base na mesma versão principal. Em atualizações para o item menor versão, o host ignora campos e propriedades de dados adicionais. Por exemplo: um dispositivo que usa a versão 1.6 do protocolo é compatível com um host que oferece suporte a versão 1.x, incluindo a versão 1.5.
Compatibilidade da versão principal
Alterações não compatíveis com versões anteriores são permitidas para alterações nas versões principais. Para oferecer suporte a várias versões principais para interoperabilidade com hosts antigos e novos, os dispositivos podem especificar várias coleções de apps no relatório descritores. Exemplo:
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#1.5"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
...
HID_END_COLLECTION,
HID_COLLECTION(HID_APPLICATION),
// Feature report 12 (read-only).
HID_REPORT_ID(12),
// Magic value: "#AndroidHeadTracker#2.4"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
...
HID_END_COLLECTION,
};
Nesse caso, o host pode enumerar todas as diferentes coleções de apps anunciada pelo dispositivo, examinando a propriedade "Descrição do sensor" para determinar as versões de protocolo que cada uma implementa e escolher as versão mais recente do protocolo compatível com o host. Quando escolhido, o host funciona com o protocolo único escolhido para o ciclo de vida do dispositivo. uma conexão com a Internet.
Apêndice: exemplo de um descritor HID
O exemplo a seguir ilustra um descritor HID válido típico. Ele usa o as macros C mais usadas, fornecidas nas Usos do sensor HID (seção 4.1).
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#1.0"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
// UUID.
HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(16),
HID_FEATURE(HID_CONST_VAR_ABS),
// Feature report 1 (read/write).
HID_REPORT_ID(1),
// 1-bit on/off reporting state.
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 1-bit on/off power state.
HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
HID_LOGICAL_MIN_8(0x00),
HID_LOGICAL_MAX_8(0x3F),
HID_PHYSICAL_MIN_8(10),
HID_PHYSICAL_MAX_8(100),
HID_REPORT_SIZE(6),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_SECOND,
HID_UNIT_EXPONENT(0xD), // 10^-3
HID_FEATURE(HID_DATA_VAR_ABS),
// Input report 1
// Orientation as rotation vector (scaled to [-pi..pi] rad).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED), // -314159265
HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12), // 314159265
HID_UNIT_EXPONENT(0x08), // 10^-8
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_8(0xE0),
HID_PHYSICAL_MAX_8(0x20),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Reference frame reset counter.
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
HID_PHYSICAL_MIN_8(0x00),
HID_PHYSICAL_MAX_8(0x00),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(HID_DATA_VAR_ABS),
HID_END_COLLECTION,
};
Apêndice 2: exemplo de um descritor HID v2.0
O exemplo a seguir ilustra um descritor HID v2.0 para um dispositivo compatível com apenas o transporte Bluetooth LE ACL.
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#2.0#1"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(25),
HID_FEATURE(HID_CONST_VAR_ABS),
// UUID.
HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(16),
HID_FEATURE(HID_CONST_VAR_ABS),
// Feature report 1 (read/write).
HID_REPORT_ID(1),
// 1-bit on/off reporting state.
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 1-bit on/off power state.
HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
HID_LOGICAL_MIN_8(0x00),
HID_LOGICAL_MAX_8(0x3F),
HID_PHYSICAL_MIN_8(10),
HID_PHYSICAL_MAX_8(100),
HID_REPORT_SIZE(6),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_SECOND,
HID_UNIT_EXPONENT(0xD), // 10^-3
HID_FEATURE(HID_DATA_VAR_ABS),
// 1-bit transport selection
HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT_ACL,
HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT_ISO,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// Input report 1
// Orientation as rotation vector (scaled to [-pi..pi] rad).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED), // -314159265
HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12), // 314159265
HID_UNIT_EXPONENT(0x08), // 10^-8
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_8(0xE0),
HID_PHYSICAL_MAX_8(0x20),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Reference frame reset counter.
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
HID_PHYSICAL_MIN_8(0x00),
HID_PHYSICAL_MAX_8(0x00),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(HID_DATA_VAR_ABS),
HID_END_COLLECTION,
};