"Trabalhando como pretendido"

O recurso de acessibilidade do Android é conhecido por causar atraso na interface do usuário. É um bug ou é um recurso? Por que isso ocorre? Nós do XDA investigamos a causa raiz.

A beleza do Android reside nas diversas maneiras pelas quais aplicativos de terceiros podem interagir com o sistema. Aplicativos gerenciadores de senhas, como Última passagem fornece a capacidade de alimentar automaticamente dados relevantes de nome de usuário/senha para praticamente qualquer tela de login. Assessor de texto permite que você reduza significativamente o tempo que gasta enviando mensagens de texto para seus amigos, permitindo criar macros de expansão de texto. Área de transferência nativa diminui o incômodo envolvido na alternância frequente entre aplicativos para copiar grandes quantidades de texto, permitindo que você toque duas vezes em qualquer campo de entrada para abrir uma área de transferência. Quem pode esquecer Ecologizar, talvez o aplicativo mais recomendado pelos entusiastas, que mantém aplicativos de fundo nocivos sob controle e pode, assim, aumentar a vida útil da bateria? Finalmente, embora menos familiarizado com a maioria dos usuários, há

Entrada automática - um plug-in Tasker projetado para automatizar toques na tela, entrada de texto, gestos de deslizar e muito mais. Todos esses aplicativos atendem a casos de uso muito diferentes, mas cada um desses aplicativos depende de uma parte muito incompreendida da funcionalidade principal do Android: Acessibilidade.

Para o usuário médio do Android, pode parecer estranho que muitos desses recursos incríveis utilizados pelo seu aplicativo favorito sejam controlados por uma configuração no acessibilidade submenu. Fazendo um aplicativo acessível normalmente significa que um aplicativo Android pode ser usado por uma pessoa com deficiência. Então, por que o LastPass, Native Clipboard, Text Aide, Greenify ou AutoInput têm um acessibilidade serviço? Além disso, por que a ativação de um serviço de acessibilidade parece causar tanto atraso na interface do usuário? Não parece importar qual versão do Android você está usando - seja Pirulito Android 5.0 ou Android 7.0 Nogado - porque o atraso causado por determinados serviços de acessibilidade pode afetar a sua experiência. Uma solução simples para este problema é simplesmente desabilitar os serviços de acessibilidade que você pode ter habilitado - mas, ao fazer isso, perdemos muitas funcionalidades úteis. Outra solução é solicitar ao Google que "conserte" o atraso de acessibilidade do Android, mas o Google afirma que a acessibilidade do Android é funcionando como pretendido. Conversamos com alguns desenvolvedores intimamente familiarizados com serviços de acessibilidade e pesquisamos como a funcionalidade funciona, e estamos aqui para testar essa afirmação: o atraso de acessibilidade do Android é um bug ou é um recurso?


Compreendendo a acessibilidade do Android

Como você pode imaginar pelo nome, Acessibilidade destina-se principalmente a desenvolvedores para fornecer funcionalidades adicionais para qualquer usuário com deficiência. Na verdade, uma rápida olhada no páginas de documentação oficial para acessibilidade revela que o Google tem uma visão bastante restrita sobre quais tipos de serviços devem ser fornecidos pelos Serviços de Acessibilidade.

Muitos usuários do Android têm habilidades diferentes que exigem que interajam com seus dispositivos Android de maneiras diferentes. Estes incluem usuários com limitações visuais, físicas ou relacionadas à idade que os impedem de ver completamente ou usando uma tela sensível ao toque e usuários com perda auditiva que podem não conseguir perceber informações e alertas sonoros.

O Android fornece recursos e serviços de acessibilidade para ajudar esses usuários a navegar melhor em seus dispositivos facilmente, incluindo conversão de texto em fala, feedback tátil, navegação por gestos, trackball e teclado direcional navegação.

do Google TalkBack, que vem pré-instalado em todos os telefones Android, é um ótimo exemplo de como deveria ser o serviço de acessibilidade “típico”. Acesso por voz leva a acessibilidade um passo adiante e permite o controle quase completo do seu telefone usando apenas a sua voz. Mas o facto de a Google pretender que os Serviços de Acessibilidade fossem utilizados desta forma não impede os desenvolvedores os implementem da maneira que quiserem - e é exatamente isso que os desenvolvedores têm feito. É exatamente pela forma como a Acessibilidade funciona que torna o recurso incrivelmente útil para usuários com ou sem deficiência.

Para simplificar um pouco as coisas, aqui está um resumo básico de como funciona a acessibilidade do Android. Um desenvolvedor cria um Serviço de acessibilidade que assina vários Eventos de acessibilidade que são enviados pelo sistema ao Serviço dependendo do atendimento ou não de determinados critérios. Quando todos os serviços estão desativados em Configurações -> Acessibilidade, o Android não coleta nem envia nenhum evento de acessibilidade. Mas quando o usuário começar a ativar os Serviços de Acessibilidade, o Android começará a monitorar e coletar apenas os Eventos de Acessibilidade solicitados pelo Serviço de Acessibilidade. Por exemplo, um Serviço de Acessibilidade que assina o Evento de Acessibilidade TYPE_WINDOW_CONTENT_CHANGED será notificado pelo sistema toda vez que ocorre uma mudança na janela atual. Outro evento de acessibilidade chamado TYPE_VIEW_CLICKED dispara toda vez o usuário clica em algum tipo de botão.

Demonstração de acessibilidade do Android. Neste vídeo eu habilitei o aplicativo Tasker monitorar para mudanças no título da janela. Isso requer a ativação do Serviço de Acessibilidade do Tasker. Você pode replicar isso criando um novo perfil no Tasker com o contexto ‘Evento’ definido como ‘Conjunto de variáveis’ e escolhendo% WIN como a variável a ser monitorada. No total, este vídeo de aproximadamente 1 minuto capturado 107 alterações na janela atual.

Esses tipos de Eventos de Acessibilidade ocorrem com grande frequência durante a interação normal do usuário. Então imagine o que acontece quando um usuário permite vários serviços de acessibilidade que solicitam que Eventos de Acessibilidade de alta frequência sejam disparados. Isso mesmo - atraso. Para mitigar isso, os desenvolvedores podem definir de forma mais restrita quais tipos de Eventos de Acessibilidade seus O Serviço deve reagir e em que contexto, como a capacidade de limitar o Serviço a reagir apenas quando em certos aplicativos ou para limitar o período de votação entre eventos. Mas, fora isso, a quantidade de sobrecarga gerada por um Serviço de Acessibilidade depende principalmente de que tipos de eventos de acessibilidade ele assina. Em essência, nem todo Serviço de Acessibilidade causará atraso. Um único Serviço de Acessibilidade que requer um Evento de alta frequência pode causar atraso, especialmente se o referido Serviço é acoplado a outro Serviço que requer outro Evento de alta frequência para ser monitorou.


Mergulhando profundamente na acessibilidade com APK Teardowns

Como você pode ver no vídeo postado acima, um Serviço de Acessibilidade que monitora alterações no conteúdo da janela pode resultam em mudanças bastante perceptíveis no desempenho da UI devido à grande quantidade de eventos de acessibilidade capturados e disparados pelo sistema. No entanto, é muito difícil determinar exatamente quanta sobrecarga é causada por um serviço de acessibilidade específico. Monitorar o LogCat geralmente não leva a lugar nenhum, pois os eventos de acessibilidade só são impressos no LogCat se o desenvolvedor do serviço de acessibilidade decidir fazê-lo. Felizmente, o pai de todos os serviços de acessibilidade do Android, Entrada automática, faz exatamente isso. E a saída do LogCat é exatamente tão confusa quanto você imagina.

AutoInput não esconde a verdade de nós. A sobrecarga causada pelo aplicativo pode ser enorme dependendo dos eventos que você monitora. Mas essa sobrecarga é necessária para que o aplicativo funcione. Para que o AutoInput intercepte cada pressionamento de tecla, cada gesto na tela, cada atualização da interface do usuário e cada pressionamento de botão, ele precisa para monitorar os respectivos Eventos de Acessibilidade. Sem esses eventos, o AutoInput não pode se conectar ao sistema e fornecer a automação de UI quase ilimitada que ele permite atualmente. Assim, todas as funções do AutoInput fazem todo o sentido no contexto da Acessibilidade. Mas para outros aplicativos, precisamos nos aprofundar um pouco mais para entender como seus serviços de acessibilidade são tratados.

Um serviço de acessibilidade atributos são definidos em um Arquivo de recurso XML dentro do APK. Portanto, podemos realizar uma Desmontagem do APK em um aplicativo com um serviço de acessibilidade para descobrir os atributos do serviço. Cada aplicativo funciona de maneira diferente, então tentarei explicar como os atributos do serviço se relacionam com a função específica que ele executa.

Área de transferência nativa

Native Clipboard é minha escolha quando se trata de gerenciadores de área de transferência. Se você está procurando um gerenciador de área de transferência altamente personalizável, Native Clipboard é um ótimo aplicativo. Ele ainda possui um componente Módulo Xposed para permitir que você mantenha pressionado o botão 'Colar' para abrir o gerenciador da área de transferência! Infelizmente, se você não tiver acesso ao Xposed Framework (como todos os usuários do Nougat), você terá que resolver para ativar o Serviço de Acessibilidade, que permitirá que você toque duas vezes em qualquer entrada de texto para abrir a área de transferência gerente. Aqui está o que isso implica.


"@string/access_decs"
android: accessibilityEventTypes="typeViewClicked|typeViewFocused|typeViewLongClicked|typeWindowStateChanged"
android: accessibilityFeedbackType="feedbackGeneric"
android: notificationTimeout="100"
android: accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
android: canRetrieveWindowContent="true"
xmlns: andro />

O Serviço de Acessibilidade da Área de Transferência Nativa solicita o disparo de um Evento de Acessibilidade toda vez que uma visualização é clicada, clicada longamente, focada ou se houver uma alteração no estado da janela. Sem ter acesso ao código-fonte, não posso dizer exatamente como funciona o Native Clipboard, mas é provável que o Native Clipboard espera que o estado da janela indique que o teclado virtual está aberto no momento e, em seguida, monitora os toques na entrada campo. O aplicativo tem um período de pesquisa de 100 ms, o que é definitivamente rápido o suficiente para reagir basicamente imediatamente às mudanças na visibilidade do teclado virtual, bem como aos toques duplos. Isso pode resultar em alguma sobrecarga na interface do usuário sempre que o usuário estiver usando o teclado virtual para digitar qualquer texto, resultando potencialmente em atraso.

Ecologizar

O próximo é o economizador de bateria favorito de todos, o Greenify. Greenify usa eventos de acessibilidade para potencializar suas funções não-root.


"@string/accessibility_service_description"
android: settingsActivity="com.oasisfeng.greenify.accessibility.AccessibilitySettings"
android: accessibilityEventTypes="typeAnnouncement|typeNotificationStateChanged|typeWindowStateChanged"
android: accessibilityFeedbackType="feedbackGeneric" android: notificationTimeout="0"
android: accessibilityFlags="flagReportViewIds"
android: canRetrieveWindowContent="true"
xmlns: andro />

Ele usa alterações no estado da janela para determinar quando a tela do telefone foi desligada e exige que você atrase a ativação da tela de bloqueio alterando uma opção nas configurações de segurança. O Greenify também receberá Eventos do tipo Anúncio ou Estado de Notificação alterado, este último desnecessário em dispositivos Android 5.0+ graças ao recurso Acesso à Notificação. No entanto, ainda receberá esses eventos, independentemente desse fato. O Greenify não deve causar muita sobrecarga por si só, mas a possibilidade permanece.

Lançador Nova

Provavelmente o aplicativo iniciador de terceiros mais popular do mercado, o Nova Launcher é um excelente exemplo de aplicativo que usa um serviço de acessibilidade com sobrecarga mínima ou nenhuma. A única razão da existência do Serviço é para auxiliar determinados dispositivos na realização de gestos.


"@string/accessibility_service_description"
android: accessibilityEventTypes=""
android: packageNames="com.teslacoilsw.launcher"
android: accessibilityFeedbackType=""
android: notificationTimeout="10000"
android: canRetrieveWindowContent="false"
xmlns: andro />

Como você pode ver, não há nenhum Evento de Acessibilidade definido no arquivo XML. Tudo o que é mencionado é o nome de um pacote – Nova Launcher. O que acontece aqui é uma solução alternativa para determinados dispositivos para os quais os gestos do Nova Launcher não funcionam. Este serviço fornecerá ao Nova Launcher todos os eventos de acessibilidade disparados de somente dentro do Nova Launcher. Parece estranho, mas aparentemente é uma maneira de corrigir os gestos da tela inicial do Nova se o seu dispositivo não funcionar com eles. Como isso solicita apenas eventos do próprio Nova, o serviço apresenta muito pouca sobrecarga.

Última passagem

Finalmente, talvez o serviço de acessibilidade mais famoso que causa atraso (provavelmente devido à sua imensa popularidade) - LastPass. A questão do atraso no LastPass é tão perceptível que a empresa tem um funcionário Página de perguntas frequentes que descreve o problema. Como afirma o FAQ, não há nada que você possa fazer a respeito do atraso, exceto desabilitar o serviço. Por que o serviço LastPass parece tão flagrante quando se trata de atraso? Vamos dar uma olhada nos atributos do Serviço.


"@string/accessibility_service_description"
android: accessibilityEventTypes="typeViewFocused|typeWindowContentChanged"
android: accessibilityFeedbackType="feedbackGeneric"
android: notificationTimeout="200"
android: accessibilityFlags="flagReportViewIds"
android: canRetrieveWindowContent="true"
android: canRequestEnhancedWebAccessibility="true"
xmlns: andro />

A verdade é que não há nada realmente fora do comum com o serviço LastPass. Ele solicita apenas dois tipos de eventos para monitorar - TYPE_VIEW_FOCUSED e TYPE_WINDOW_CONTENT_CHANGED. Ele faz isso porque precisa saber quando o conteúdo de um aplicativo/página da web mudou/entra em foco e, em seguida, recupera o conteúdo da janela atual para procurar quaisquer campos de entrada de senha. Mas como o serviço faz isso constantemente em dois eventos de acessibilidade que disparam com extrema frequência, isso resulta em atraso. Essa é a triste verdade.


Vivendo com o atraso

Quando lemos pela primeira vez que o Google estava fechando relatórios de bugs sobre atraso de acessibilidade porque o recurso estava “funcionando conforme planejado”, ficamos tão perplexos e chateados quanto muitos de vocês. Mas, em vez de aceitar a explicação pelo seu valor nominal, decidimos examinar o assunto nós mesmos para determinar a verdade. Então, quando o Googler na página de relatório de bug disse o seguinte:

Olá, este problema persiste nas versões do Android. Além disso, sempre haverá um atraso adicional quando um serviço de acessibilidade estiver ativado. Isso porque o dispositivo, além da UI padrão, fornece muitas informações aos serviços de acessibilidade para que possam fornecer uma experiência de usuário alternativa a esses usuários.

Nós chegamos a entender por que isso é comportamento pretendido. Os apps que usam os Serviços de Acessibilidade de maneira não intencional pelo Google sempre incorrerão em alguma sobrecarga de desempenho; esse custo é simplesmente necessário para fornecer aos Serviços a infinidade de informações que o Android Accessibility dispara em segundo plano. O atraso do Android com os Serviços de Acessibilidade é não é um bug, mas um recurso. Um recurso com o qual teremos que conviver, a menos que todo o sistema seja retrabalhado, e não consigo imaginar como isso seria feito para acomodar tantos conjuntos de recursos diferentes de tantos aplicativos diferentes.

No mínimo, os desenvolvedores do LastPass não aceitariam isso sentados. Seus desenvolvedores trabalharam com os desenvolvedores do Chromium para otimizar o suporte de acessibilidade, talvez ativando o suporte LastPass através do uso de APIs em vez de ativar um serviço de acessibilidade. A otimização em torno da sobrecarga incorrida pelos Serviços de Acessibilidade é uma possibilidade, mas como muitos desenvolvedores observaram implicitamente em nos fóruns do Chromium, é simplesmente um curativo que não resolverá o fato de que usos não intencionais dos Serviços de Acessibilidade podem resultar em atraso.


Agradecimentos especiais ao desenvolvedor do AutoInput, joaomgcd, por responder muitas das minhas perguntas sobre acessibilidade!